bzoj 3262 陌上花开

        本质是一个三维偏序,一位排序后cdq分治,一维在子函数里排序,一维用树状数组维护。

        把三维相等的合并到一个里面。

        

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define N 100005
 6 using namespace std;
 7 int n,k,m;
 8 struct node
 9 {
10     int x,y,z,num,op;
11     int yuan;
12     bool operator == (const node &b)
13     {
14         return x==b.x&&y==b.y&&z==b.z;
15     }
16 }a[N],b[N];
17 int shan[N];
18 int ans[N];
19 bool cmp1(node aa,node bb)
20 {
21     if(aa.num==0)return 0;
22     if(bb.num==0)return 1;
23     if(aa.x!=bb.x)return aa.x<bb.x;
24     if(aa.y!=bb.y)return aa.y<bb.y;
25     if(aa.z!=bb.z)return aa.z<bb.z;
26     
27 }
28 bool cmp2(node aa,node bb)
29 {
30     if(aa.y!=bb.y)return aa.y<bb.y;
31     return aa.op<bb.op;
32 }
33 int c[200005];
34 void add(int x,int y)
35 {
36     for(int i=x;i<=k;i+=(i&(-i)))c[i]+=y;
37 }
38 int qur(int x)
39 {
40     int now=0;
41     for(int i=x;i;i-=(i&(-i)))now+=c[i];
42     return now;
43 }
44 void solve(int l,int r)
45 {
46     if(l==r)return ;
47     int mid=(l+r)>>1;
48     solve(l,mid);solve(mid+1,r);
49     int cnt=0;
50     for(int i=l;i<=mid;i++)
51     {
52         b[++cnt]=a[i];
53         b[cnt].op=1;
54     }
55     for(int i=mid+1;i<=r;i++)
56     {
57         b[++cnt]=a[i];
58         b[cnt].op=2;
59     }
60     sort(b+1,b+cnt+1,cmp2);
61     for(int i=1;i<=cnt;i++)
62     {
63         if(b[i].op==1)add(b[i].z,b[i].num);
64         else ans[b[i].yuan]+=qur(b[i].z);
65     }
66     for(int i=1;i<=cnt;i++)if(b[i].op==1)add(b[i].z,-b[i].num);
67 }
68 int zui[N];
69 int main()
70 {
71     scanf("%d%d",&n,&k);m=n;
72     for(int i=1;i<=n;i++)
73     {
74         scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
75         a[i].num=1;
76     }
77     sort(a+1,a+n+1,cmp1);
78     for(int i=1;i<=n;i++)
79     {
80         if(a[i]==a[i-1])
81         {
82             a[shan[i-1]].num++;
83             shan[i]=shan[i-1];
84             a[i].num--;
85         }
86         else shan[i]=i;
87     }
88     sort(a+1,a+n+1,cmp1);
89     while(a[n].num==0)n--;
90     for(int i=1;i<=n;i++)a[i].yuan=i;
91     solve(1,n);
92     for(int i=1;i<=n;i++)zui[ans[a[i].yuan]+a[i].num-1]+=a[i].num;
93     for(int i=0;i<=m-1;i++)printf("%d\n",zui[i]);
94     return 0;
95 }

 

posted @ 2016-12-10 13:57  SD_le  阅读(169)  评论(0编辑  收藏  举报
重置按钮