标签:
题意: 求满足最大的上升序列长度和个数,对于一个三元组(x,y,z) 要求x1<=x2,y1<=y2,z1<=z2
解析: CDQ处理,先把z值离散化,再把所有的三元组按照(x,y,z)排好序,CDQ分治处理 CDQ思想:对于区间[l,r],先递归处理左半区间[l,mid](左边的信息已经更新好了), 再处理当前区间,用前mid个元素更新后半部分的值,一般是插入到某种数据结构中, 后半部分通过查询更新值,最后处理右半区间[mid+1,r],相当于从左到右处理完所有 的元素。具体实现见代码。
代码
#include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; #define fi first #define se second typedef pair<int,int> par; const int maxn=100005; int N,ms,A[maxn];//A用于离散化z值 par dp[maxn],tree[maxn],zero(0,0); //dp的fi保存长度,se保存大小,tree用于树状数组 struct node { int x,y,z,id; node(int x=0,int y=0,int z=0):x(x),y(y),z(z){} bool operator < (const node& t) const //依次排x,y,z { if(x!=t.x) return x<t.x; if(y!=t.y) return y<t.y; return z<t.z; } }nod[maxn],tnod[maxn]; void init() { scanf("%d",&N); int x,y,z; for(int i=0;i<N;i++) { scanf("%d%d%d",&x,&y,&z); nod[i]=node(x,y,z); A[i]=z; } sort(nod,nod+N); sort(A,A+N); ms=0; for(int i=1;i<N;i++) if(A[ms]!=A[i]) A[++ms]=A[i]; for(int i=0;i<N;i++) { nod[i].z=lower_bound(A,A+ms+1,nod[i].z)-A+1; nod[i].id=i; } } int lowbit(int x){ return x&(-x); } void Update(par& a,const par& b) //更新 { if(a.fi<b.fi) a=b; //长度小 else if(a.fi==b.fi) a.se+=b.se; //加上这么多种情况 } void Modify(int i,const par& b){ for(;i<=ms;i+=lowbit(i)) Update(tree[i],b); } par Query(int i) { par ret=zero; for(;i>0;i-=lowbit(i)) Update(ret,tree[i]); return ret; } void Recover(int i){ for(;i<=ms;i+=lowbit(i)) tree[i]=zero; } void CDQ(int l,int r) { if(l==r) return; if(l>r) return; int mid=(l+r)/2; CDQ(l,mid);//先处理左边边 int k=0; for(int i=l;i<=r;i++) { tnod[k]=nod[i]; tnod[k++].x=0; } sort(tnod,tnod+k); for(int i=0;i<k;i++) { node& t=tnod[i]; if(t.id<=mid) Modify(t.z,dp[t.id]); //左边已经处理过,只需要插入即可 else // 更新右边 { par a=Query(t.z); a.fi++; Update(dp[t.id],a); } } for(int i=0;i<k;i++) //一定要恢复,不然会影响后面的 { node& t=tnod[i]; if(t.id<=mid) Recover(t.z); } CDQ(mid+1,r); //再处理右边 } int main() { int T; scanf("%d",&T); while(T--) { init(); for(int i=0;i<N;i++) dp[i].fi=dp[i].se=1; CDQ(0,N-1); par ans=zero; for(int i=0;i<N;i++) Update(ans,dp[i]); printf("%d %d\n",ans.fi,ans.se); } return 0; }
Hdu4742-Pinball Game 3D(cdq分治+树状数组)
标签:
原文地址:http://www.cnblogs.com/wust-ouyangli/p/5764135.html