# cdq分治入门--BZOJ3262: 陌上花开

n<=100000个人，每个人三个属性Ai,Bi,Ci，一个人i的等级为Ai>=Aj,Bi>=Bj,Ci>=Cj的人数，求每个等级有多少人。

 1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<algorithm>
5 //#include<iostream>
6 using namespace std;
7
8 int n,m;
9 #define maxn 200011
10 int ord[maxn],tmpord[maxn];
11 struct BIT
12 {
13     int a[maxn];
14     BIT() {memset(a,0,sizeof(a));}
15     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
16     int query(int x) {int ans=0;for (;x;x-=x&-x) ans+=a[x];return ans;}
17 }t;
18
19 struct Point
20 {
21     int x,y,z,cnt;
22     bool operator < (const Point &b) const
23     {return x<b.x || (x==b.x && y<b.y) || (x==b.x && y==b.y && z<b.z);}
24 }q[maxn],p[maxn];
25 int ans[maxn],ansnum[maxn];
26 void solve(int L,int R)
27 {
28     if (L==R) {ans[L]+=p[L].cnt-1;ord[L]=L;return;}
29     const int mid=(L+R)>>1;
30     solve(L,mid);
31     solve(mid+1,R);
32     int i=L,j=mid+1,k=L;
33     while (i<=mid && j<=R)
34     {
35         if (p[ord[i]].y<=p[ord[j]].y)
36         {
37             tmpord[k++]=ord[i];
39             i++;
40         }
41         else
42         {
43             tmpord[k++]=ord[j];
44             ans[ord[j]]+=t.query(p[ord[j]].z);
45             j++;
46         }
47     }
48     for (;j<=R;j++) ans[ord[j]]+=t.query(p[ord[j]].z),tmpord[k++]=ord[j];
50     for (;i<=mid;i++) tmpord[k++]=ord[i];
51     for (int x=L;x<=R;x++) ord[x]=tmpord[x];
52 }
53
54 int lisan[maxn];
55 int main()
56 {
57     scanf("%d%d",&n,&m);
58     for (int i=1;i<=n;i++)
59     {
60         scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
61         lisan[i]=q[i].z;
62     }
63     sort(lisan+1,lisan+1+n);
64     for (int i=1;i<=n;i++) q[i].z=lower_bound(lisan+1,lisan+1+n,q[i].z)-lisan;
65     sort(q+1,q+1+n);
66     int tot=0;q[0].x=-0x3f3f3f3f;
67     for (int i=1;i<=n;i++)
68     {
69         if (q[i-1].x==q[i].x && q[i-1].y==q[i].y && q[i-1].z==q[i].z) p[tot].cnt++;
70         else p[++tot]=q[i],p[tot].cnt=1;
71     }
72     solve(1,tot);
73     for (int i=1;i<=tot;i++) ansnum[ans[i]]+=p[i].cnt;
74     for (int i=0;i<n;i++) printf("%d\n",ansnum[i]);
75     return 0;
76 }
View Code

posted @ 2017-11-23 19:52  Blue233333  阅读(149)  评论(0编辑  收藏  举报