Description
有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
Input
第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性
Output
包含N行,分别表示评级为0...N-1的每级花的数量。
Sample Input
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
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
1
3
0
1
0
1
0
0
1
HINT
1 <= N <= 100,000, 1 <= K <= 200,000
三维偏序集,黄学长告诉我们可以
1.树状数组+treap √
2.cdq分治
目前只会树套树的做法,然而我的树套树真心很弱
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #define M 5000005 6 using namespace std; 7 int n,m,sz,tmp; 8 int root[200005],ans[100005],sum[100005]; 9 int size[M],ls[M],rs[M],v[M],w[M],rnd[M]; 10 struct node{int a,b,c;}a[100005]; 11 int lowbit(int x){return x&(-x);} 12 bool cmp(node a,node b){ 13 if (a.a==b.a&&a.b==b.b) return (a.c<b.c); 14 if (a.a==b.a) return (a.b<b.b); 15 return (a.a<b.a); 16 } 17 void updata(int x){size[x]=size[ls[x]]+size[rs[x]]+w[k];} 18 void lturn(int &k){int t=rs[k];rs[k]=ls[t];ls[t]=k;updata(k);updata(t);k=t;} 19 void rturn(int &k){int t=ls[k];ls[k]=rs[t];rs[t]=k;updata(k);updata(t);k=t;} 20 void ins(int &k,int num){ 21 if (!k){sz++;k=sz;rnd[k]=rand();v[k]=num;size[k]=w[k]=1;return;} 22 size[k]++; 23 if (v[k]==num) {w[k]++;return;} 24 else if (v[k]>num){ins(ls[k],num);if (rnd[ls[k]]<rnd[k]) rturn(k);} 25 else {ins(rs[k],num);if (rnd[rs[k]]<rnd[k]) lturn(k);} 26 } 27 28 void getrank(int k,int num){ 29 if (!k) return; 30 int l=ls[k],r=rs[k]; 31 if (v[k]==num) {tmp+=size[l]+w[k];return;} 32 else if (v[k]>num) getrank(l,num); 33 else if (v[k]<num){tmp+=size[l]+w[k];getrank(r,num);} 34 } 35 36 void ask(int x,int num){ 37 for (int i=x;i;i-=lowbit(i)) 38 getrank(root[i],num); 39 } 40 41 void insert(int x,int num){ 42 for (int i=x;i<=m;i+=lowbit(i)) 43 ins(root[i],num); 44 } 45 46 int main(){ 47 scanf("%d%d",&n,&m); 48 for (int i=1;i<=n;i++) scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c); 49 sort(a+1,a+n+1,cmp); 50 for (int i=1;i<=n;i++){ 51 if (a[i].a==a[i+1].a&&a[i].b==a[i+1].b&&a[i].c==a[i+1].c&&i!=n) sum[i+1]=sum[i]+1; 52 else{ 53 tmp=0; 54 ask(a[i].b,a[i].c); 55 ans[tmp]+=sum[i]+1; 56 } 57 insert(a[i].b,a[i].c); 58 } 59 for (int i=0;i<n;i++)printf("%d ",ans[i]); 60 }