有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
第一维排序,剩下两维用CDQ分治
1 <= N <= 100,000, 1 <= K <= 200,000
树套树 CDQ分治
/* *********************************************** Author :CKboss Created Time :2015年08月02日 星期日 16时32分58秒 File Name :BZOJ3262_2.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=200200; /*************BIT******************/ int tree[maxn],color[maxn],C; inline int lowbit(int x) { return x&(-x); } void Add(int p,int v) { for(int i=p;i<maxn;i+=lowbit(i)) { if(color[i]!=C) tree[i]=0; color[i]=C; tree[i]+=v; } } int Sum(int p) { int ret=0; for(int i=p;i;i-=lowbit(i)) { if(color[i]==C) ret+=tree[i]; } return ret; } /****************NODE**************/ int n,S; struct Flower { int a,b,c,level,num; void toString() { printf("(%d,%d,%d) level: %d num: %d\n",a,b,c,level,num); } }flower[maxn]; bool cmp(Flower a,Flower b){ if (a.a==b.a && a.b==b.b) return a.c<b.c; if (a.a==b.a) return a.b<b.b; return a.a<b.a; } bool cmpCDQ(Flower a,Flower b){ if (a.b==b.b) return a.c<b.c; return a.b<b.b; } /***************CDQ****************/ void CDQ(int left,int right) { if(left==right) return ; int mid=(left+right)/2; CDQ(left,mid);CDQ(mid+1,right); sort(flower+left,flower+mid+1,cmpCDQ); sort(flower+mid+1,flower+right+1,cmpCDQ); int i,j;C++; for(j=mid+1,i=left;j<=right;j++) { for(;flower[i].b<=flower[j].b&&i<=mid;i++) Add(flower[i].c,flower[i].num); flower[j].level+=Sum(flower[j].c); } } int ans[maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d",&n,&S); for(int i=1,a,b,c;i<=n;i++) { scanf("%d%d%d",&a,&b,&c); flower[i]=(Flower){a,b,c,0,1}; } sort(flower+1,flower+n+1,cmp); int tot=1; for(int i=2;i<=n;i++) { if(flower[i].a!=flower[tot].a ||(flower[i].b!=flower[tot].b) ||(flower[i].c!=flower[tot].c)) { tot++; flower[tot]=flower[i]; } else { flower[tot].num++; } } CDQ(1,tot); for(int i=1;i<=tot;i++) ans[flower[i].level+flower[i].num-1]+=flower[i].num; for(int i=0;i<n;i++) printf("%d\n",ans[i]); return 0; }