Hdu 5324 Boring Class (cdq分治)
来源:互联网 发布:安正时尚集团 知乎 编辑:程序博客网 时间:2024/05/17 23:42
解析:因为是最小字典序,所以从右往左DP。
dp[i] = max(dp[j]+1) i < j,L[i]>=L[j],R[i]<=R[j]
因为这是三维上的问题,自然的就能想到cdq分治了。
在一个区间[l,r]内,先对[mid+1,r]递归,按L[]排序后建立一个对R的线段树,来计算[mid+1,r]的影响,再递归[l,r]。
这里说的比较笼统,不过熟悉cdq分治的同学应该能立马明白我说的什么吧!
[code]:
#include<cstdio>#include<cstring>#include<algorithm>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int maxn = 1e5+5;int mc[2*maxn],hah;int n,L[maxn],R[maxn],dp[maxn],pre[maxn];int C[8*maxn];int que[maxn];void init(){ hah = 0; memset(pre,-1,(n+1)*sizeof(int));}void push_up(int rt){ if(dp[C[rt<<1]] != dp[C[rt<<1|1]]){ C[rt] = dp[C[rt<<1]]>dp[C[rt<<1|1]]?C[rt<<1]:C[rt<<1|1]; }else C[rt] = min(C[rt<<1],C[rt<<1|1]);}void build(int l,int r,int rt){ C[rt] = 0; if(l == r) return; int mid = (l+r)>>1; build(lson);build(rson);}void update(int k,int x,int l,int r,int rt){ if(l == r){ if(dp[x]>dp[C[rt]]) C[rt] = x; else if(dp[x]==dp[C[rt]]) C[rt] = min(C[rt],x); return; } int mid = (l+r)>>1; if(k <= mid) update(k,x,lson); else update(k,x,rson); push_up(rt);}void debug(int l,int r,int rt){ if(l ==r){ printf("%d ",C[rt]); return; } int mid = (l+r)>>1; debug(lson);debug(rson);}void clr(int k,int l,int r,int rt){ C[rt] = 0; if(l == r) return; int mid = (l+r)>>1; if(k <= mid) clr(k,lson); else clr(k,rson);}int query(int a,int b,int l,int r,int rt){ if(a <= l&&r <= b) return C[rt]; if(l > b||r < a) return 0; int p1,p2,mid = (l+r)>>1; p1 = query(a,b,lson);p2 = query(a,b,rson); if(dp[p1]!=dp[p2]) return dp[p1]>dp[p2]?p1:p2; else return min(p1,p2);}bool cmp(const int &i,const int &j){ return L[i]!=L[j]?L[i]<L[j]:i > j;}void cdq(int l,int r){ if(l>=r) return; int u,v,i,j,mid,len; mid = (l+r)>>1; cdq(mid+1,r); len = 0; for(i = l;i <= r;i++) que[len++] = i; sort(que,que+len,cmp); for(i = 0;i < len;i++){ u = que[i]; if(u > mid){ update(R[u],u,1,hah,1); }else{ v = query(R[u],hah,1,hah,1); if(!v) continue; if(dp[u]<dp[v]+1){ dp[u] = dp[v]+1;pre[u] = v; }else if(dp[u]==dp[v]+1) pre[u] = min(pre[u],v); } } for(i = 0;i < len;i++){ if(que[i]>mid) clr(R[que[i]],1,hah,1); } cdq(l,mid);}int main(){ int i,j; while(~scanf("%d",&n)){ init(); for(i = 1;i <= n;i++) scanf("%d",&L[i]); for(i = 1;i <= n;i++) scanf("%d",&R[i]); for(i = 1;i <= n;i++){ mc[hah++] = L[i];mc[hah++] = R[i]; dp[i] = 1; } sort(mc,mc+hah); hah = unique(mc,mc+hah)-mc; for(i = 1;i <= n;i++){ L[i] = lower_bound(mc,mc+hah,L[i])-mc+1; R[i] = lower_bound(mc,mc+hah,R[i])-mc+1; } build(1,hah,1); cdq(1,n); int tmp = -1; for(i = 1;i <= n;i++){ tmp = max(tmp,dp[i]); } for(i = 1;i <= n;i++) if(dp[i]==tmp) break; printf("%d\n%d",dp[i],i); while(pre[i]!=-1){ printf(" %d",pre[i]); i = pre[i]; } putchar('\n'); } return 0;}
0 0
- HDU 5324 Boring Class【cdq分治】
- HDU 5324 Boring Class(CDQ分治)
- Hdu 5324 Boring Class (cdq分治)
- HDU 5324 Boring Class 树套树 或 CDQ分治
- hdu 5324 Boring Class cdq分治+树状数组+离散化
- 【cdq分治】 HDOJ 5324 Boring Class
- hdu 5324 Boring Class(15多校第三场1009)(cdq分治)
- hdu 5324 Boring Class(树状数组+笛卡尔树 | 树状数组+cdq分治)
- HDU-5324 cdq分治
- HDU 5324 Boring Class(分治+树状数组)
- hdu 5324 Boring Class
- hdu 5324 树套树、cdq分治
- HDU 5324 (CDQ分治 树状数组)
- HDU 4456 CDQ分治
- HDU - 1166 CDQ分治
- Hdu 5618 CDQ分治
- hdu 5324 Boring Class (树套树)
- hdu 5324 Boring Class 2015多校联合训练赛3 分治,最长不降子序列,最小字典序
- 【HDU】5458 Stability(2015 ACM/ICPC Shenyang Online)
- FIRST DAY`S EVE
- LeetCode:链表逆置
- 北航14年上机题
- 第一篇博客
- Hdu 5324 Boring Class (cdq分治)
- 2016暑假算法学习开始
- Codeforces Round #310 (Div. 2)-A. Case of the Zeros and Ones
- UVa 122 - Trees on the level
- 武大WOJ账户的安全性
- 前景检测算法(十四)--SuBSENSE算法
- 1040. Longest Symmetric String (25)
- 可重录入与不可重录入和ELF文件的相关问题
- 在LinearLayout里面动态添加ImageView