「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 }

 

posted @ 2018-03-08 14:00  Cupcake  阅读(131)  评论(0编辑  收藏  举报