# cdq分治 bzoj 3262 陌上花开 and luogu 3810

10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1

## Sample Output

3
1
3
0
1
0
1
0
0
1

cdq入门题， 三维偏序，cdq最好的地方在于可以降一维数据结构。
cdq核心是要考虑左区间对右区间的影响。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int const N=100000+10;
4 struct query{
5   int x,y,z,id;
6   bool operator < (const query &rhs) const{
7     if(x!=rhs.x) return x<rhs.x;
8     if(y!=rhs.y) return y<rhs.y;
9     return z<rhs.z;
10   }
11 }q[N],t[N];
12 int ans[N],n,k,c[N<<1],num[N],cnt[N];
13 inline int getsum(int x){
14   int s=0;
15   for(int i=x;i;i-=(i&-i))
16     s+=c[i];
17   return s;
18 }
19 void update(int x,int v){
20   for(int i=x;i<=k;i+=(i&(-i)))
21     c[i]+=v;
22 }
23 void cdq(int l,int r)
24 {
25   if(l==r) return;
26   int mid=(l+r)/2;
27   cdq(l,mid);
28   cdq(mid+1,r);
29   int i=l,j=mid+1,k=l;
30   while (i<=mid && j<=r){
31     if(q[i].y<=q[j].y)
32       {
33        // if(l==1 && r==7)  cout<<getsum(3)<<" 333"<<endl;
34         update(q[i].z,cnt[q[i].id]),t[k++]=q[i++];
35       }
36     else {
37       ans[q[j].id]+=getsum(q[j].z);
38       if(q[j].x==2 && q[j].y==1 && q[j].z==3){
39         //for(int k=l;k<=r;k++)
40          // cout<<q[k].x<<" "<<q[k].y<<" "<<q[k].z<<" "<<q[k].id<<"nima"<<" "<<getsum(3)<<i<<" "<<j<<" "<<endl;
41        // cout<<"###"<<q[j].id<<" "<<l<<" "<<r<<" "<<ans[q[j].id]<<endl;
42       }
43       t[k++]=q[j++];
44     }
45   }
46   while (i<=mid) update(q[i].z,cnt[q[i].id]),t[k++]=q[i++];
47   while (j<=r) ans[q[j].id]+=getsum(q[j].z),t[k++]=q[j++];
48   //if(l==5 && r==7) cout<<"#####################"<<getsum(3)<<endl;
49   for(int i=l;i<=mid;i++) update(q[i].z,-cnt[q[i].id]);
50   for(int i=l;i<=r;i++) q[i]=t[i];
51  // cout<<"end "<<l<<" "<<r<<" "<<getsum(3)<<endl;
52 }
53 int main(){
54   //freopen("std.out","w",stdout);
55   scanf("%d%d",&n,&k);
56   for(int i=1;i<=n;i++)
57   {
58     scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
59   }
60   sort(q+1,q+n+1);
61   cnt[1]=1;
62   int m=1;
63   for(int i=2;i<=n;i++)
64     if(q[i].x!=q[i-1].x || q[i].y!=q[i-1].y || q[i].z!=q[i-1].z)
65       q[++m]=q[i],cnt[m]=1;
66     else cnt[m]++;
67   //for(int i=1;i<=m;i++) cout<<q[i].x<<" "<<q[i].y<<" "<<q[i].z<<cnt[i]<<endl;
68   for(int i=1;i<=m;i++) q[i].id=i;
69  // cout<<getsum(3)<<"woma"<<endl;
70   cdq(1,m);
71   //for(int i=1;i<=m;i++)
72    // cout<<q[i].x<<" "<<q[i].y<<" "<<q[i].z<<" "<<ans[q[i].id]<<" "<<cnt[q[i].id]<<endl;
73   for(int i=1;i<=m;i++){
74     num[ans[i]+cnt[i]-1]+=cnt[i];
75    // cout<<ans[i]<<" "<<cnt[i]<<endl;
76   }
77   for(int i=0;i<n;i++)
78     printf("%d\n",num[i]);
79   return 0;
80 }
View Code

posted @ 2019-08-19 15:26  zjxxcn  阅读(113)  评论(0编辑  收藏  举报