「BZOJ1935」[SHOI2007]园丁的烦恼
二维偏序问题
网上某篇博客讲三维偏序时拿这题举了例子
于是我辛辛苦苦码了一个三维偏序CDQ分治挂了N发后才A
然后冷静分析了一下发现是二维偏序啊!
然后又发现既然是二维偏序那么一发树状数组就可以水过啊!!
好气呀!
三维偏序CDQ分治版
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=500010,K=10000010; 4 int n,m,maxy,totq,ans[N]; 5 inline int read(){ 6 int x=0,w=1;char c=0; 7 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();} 8 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar(); 9 return x*w; 10 } 11 struct Node{ 12 int type,x,y,v; 13 bool operator<(const Node& k)const{ 14 if(x==k.x&&y==k.y) return type<k.type; 15 if(y==k.y) return x<k.x; 16 return y<k.y; 17 } 18 }que[N*5],temp[N*5]; 19 int cmp(const Node& x,const Node& y){ 20 if(x.x==y.x&&x.y==y.y) return x.type<y.type; 21 if(x.x==y.x) return x.y<y.y; 22 return x.x<y.x; 23 } 24 int tree[K]; 25 inline int lowbit(int k){return k&(-k);} 26 inline void add(int k,int x){ 27 while(k<=maxy) tree[k]+=x,k+=lowbit(k); 28 return; 29 } 30 inline int query(int k){ 31 int res=0; 32 while(k) res+=tree[k],k-=lowbit(k); 33 return res; 34 } 35 inline void reset(int k){ 36 while(k<=maxy){ 37 if(tree[k]) tree[k]=0;else return; 38 k+=lowbit(k); 39 } 40 return; 41 } 42 void cdq(int l,int r){ 43 if(l>=r) return; 44 int mid=(l+r)>>1; 45 cdq(l,mid);cdq(mid+1,r); 46 int pi=l,pj=mid+1,pt=l; 47 while(pi<=mid&&pj<=r) 48 if(que[pi]<que[pj]){ 49 if(que[pi].type==1) add(que[pi].y,que[pi].v); 50 temp[pt++]=que[pi++]; 51 }else{ 52 if(que[pj].type>1) ans[que[pj].v]+=(que[pj].type==2?1:-1)*query(que[pj].y); 53 temp[pt++]=que[pj++]; 54 } 55 while(pi<=mid) temp[pt++]=que[pi++]; 56 while(pj<=r){ 57 if(que[pj].type>1) ans[que[pj].v]+=(que[pj].type==2?1:-1)*query(que[pj].y); 58 temp[pt++]=que[pj++]; 59 } 60 for(int i=l;i<=r;i++){ 61 if(i<=mid&&que[i].type==1) reset(que[i].y); 62 que[i]=temp[i]; 63 } 64 return; 65 } 66 int main(){ 67 int t1,t2,t3,t4; 68 n=read(),m=read(); 69 for(int i=1;i<=n;i++){ 70 t1=read(),t2=read(),t1++,t2++,maxy=max(maxy,t2); 71 que[++totq]=(Node){1,t1,t2,1}; 72 } 73 for(int i=1;i<=m;i++){ 74 t1=read(),t2=read(),t3=read(),t4=read(); 75 t1++,t2++,t3++,t4++; 76 if(t2>1e7+1||t1>1e7+1||t3<1||t4<1) continue; 77 t1=max(t1,1);t2=max(t2,1); 78 t3=min(t3,int(1e7)+1); 79 t4=min(t4,int(1e7)+1); 80 maxy=max(maxy,t4); 81 que[++totq]=(Node){2,t3,t4,i}; 82 if(t1>1&&t2>1) que[++totq]=(Node){2,t1-1,t2-1,i}; 83 if(t2>1) que[++totq]=(Node){3,t3,t2-1,i}; 84 if(t1>1) que[++totq]=(Node){3,t1-1,t4,i}; 85 } 86 sort(que+1,que+totq+1,cmp); 87 cdq(1,totq); 88 for(int i=1;i<=m;i++) printf("%d\n",ans[i]); 89 return 0; 90 }
二维偏序CDQ分治版
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=500010,K=10000010; 4 int n,m,maxy,totq,ans[N]; 5 inline int read(){ 6 int x=0,w=1;char c=0; 7 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();} 8 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar(); 9 return x*w; 10 } 11 struct Node{ 12 int type,x,y,v; 13 bool operator<(const Node& k)const{ 14 if(x==k.x&&y==k.y) return type<k.type; 15 if(y==k.y) return x<k.x; 16 return y<k.y; 17 } 18 }que[N*5],temp[N*5]; 19 int cmp(const Node& x,const Node& y){ 20 if(x.x==y.x&&x.y==y.y) return x.type<y.type; 21 if(x.x==y.x) return x.y<y.y; 22 return x.x<y.x; 23 } 24 void cdq(int l,int r){ 25 if(l>=r) return; 26 int mid=(l+r)>>1; 27 cdq(l,mid);cdq(mid+1,r); 28 int pi=l,pj=mid+1,pt=l,sum=0; 29 while(pi<=mid&&pj<=r) 30 if(que[pi]<que[pj]){ 31 if(que[pi].type==1) sum++; 32 temp[pt++]=que[pi++]; 33 }else{ 34 if(que[pj].type>1) ans[que[pj].v]+=(que[pj].type==2?1:-1)*sum; 35 temp[pt++]=que[pj++]; 36 } 37 while(pi<=mid) temp[pt++]=que[pi++]; 38 while(pj<=r){ 39 if(que[pj].type>1) ans[que[pj].v]+=(que[pj].type==2?1:-1)*sum; 40 temp[pt++]=que[pj++]; 41 } 42 for(int i=l;i<=r;i++) que[i]=temp[i]; 43 return; 44 } 45 int main(){ 46 int t1,t2,t3,t4; 47 n=read(),m=read(); 48 for(int i=1;i<=n;i++){ 49 t1=read(),t2=read(),t1++,t2++,maxy=max(maxy,t2); 50 que[++totq]=(Node){1,t1,t2,1}; 51 } 52 for(int i=1;i<=m;i++){ 53 t1=read(),t2=read(),t3=read(),t4=read(); 54 t1++,t2++,t3++,t4++; 55 if(t2>1e7+1||t1>1e7+1||t3<1||t4<1) continue; 56 t1=max(t1,1);t2=max(t2,1); 57 t3=min(t3,int(1e7)+1); 58 t4=min(t4,int(1e7)+1); 59 maxy=max(maxy,max(t2,t4)); 60 que[++totq]=(Node){2,t3,t4,i}; 61 if(t1>1&&t2>1) que[++totq]=(Node){2,t1-1,t2-1,i}; 62 if(t2>1) que[++totq]=(Node){3,t3,t2-1,i}; 63 if(t1>1) que[++totq]=(Node){3,t1-1,t4,i}; 64 } 65 sort(que+1,que+totq+1,cmp); 66 cdq(1,totq); 67 for(int i=1;i<=m;i++) printf("%d\n",ans[i]); 68 return 0; 69 }