bzoj 3262: 陌上花开

来源:互联网 发布:电商平台常用的js特效 编辑:程序博客网 时间:2024/06/11 01:25

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

Sample Output

3
1
3
0
1
0
1
0
0
1

HINT

1 <= N <= 100,000, 1 <= K <= 200,000


CDQ分治。先按照x排序。然后我们用归并排序的方法排序y。同时把z放进树状数组

因为x排序好了。所以归并的时候保证左半边的x小于等于右半边。那么我们只需要在放入右半边数的时候记录有几个z比它小就可以了

【果然状态不行各种傻逼错调了好久】

#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;struct number{     int x,y,z;     int p;     int s;}a[100001],b[100001],c[100001];int rank[100001];int sx[100001];inline bool cmpx(number x,number y){     if(x.x<y.x)          return true;     if(x.x==y.x)     {          if(x.y<y.y)               return true;          if(x.y==y.y)               if(x.z<y.z)                    return true;     }     return false;}int tr[200001];int k;inline int lowbit(int x){     return x&(-x);}inline void add(int x,int xx){     int i;     for(i=x;i<=k;i+=lowbit(i))          tr[i]+=xx;}inline int ask(int x){     int i;     int ans=0;     for(i=x;i>=1;i-=lowbit(i))          ans+=tr[i];     return ans;}inline void solve(int l,int r){ int mid=(l+r)/2; if(l!=r) {      solve(l,mid);      solve(mid+1,r);      int i1=l,i2=mid+1;      int p=0;      //memset(tr,0,sizeof(tr));      while(i1<=mid&&i2<=r)      {           if(a[i1].y<=a[i2].y)           {                p++;                c[p]=a[i1];                add(c[p].z,c[p].s);                i1++;           }           else           {                p++;                c[p]=a[i2];                rank[c[p].p]+=ask(c[p].z);                i2++;           }      }      if(i1<=mid)      {           int i;               for(i=i1;i<=mid;i++)               {                    p++;                    c[p]=a[i];                    add(c[p].z,c[p].s);               }      }      else if(i2<=r)      {           int i;               for(i=i2;i<=r;i++)               {                    p++;                    c[p]=a[i];                    rank[c[p].p]+=ask(c[p].z);               }      }      int i;      for(i=l;i<=mid;i++)           add(a[i].z,-a[i].s);      for(i=l;i<=r;i++)           a[i]=c[i-l+1]; }}int main(){//     freopen("test.in","r",stdin);//     freopen("test.out","w",stdout);     int n;     scanf("%d%d",&n,&k);     int i;     for(i=1;i<=n;i++)     {          scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);          b[i].p=i;     }     sort(b+1,b+1+n,cmpx);     int t=0;     for(i=1;i<=n;i++)     {          if(b[i].x!=b[i-1].x||b[i].y!=b[i-1].y||b[i].z!=b[i-1].z)          {               t++;               a[t]=b[i];               a[t].s=1;               a[t].p=t;          }          else               a[t].s++;     }     for(i=1;i<=t;i++)          b[i]=a[i];     solve(1,t);     //for(i=1;i<=t;i++)       //   printf("%d\n",rank[i]);     for(i=1;i<=t;i++)          sx[rank[i]+b[i].s]+=b[i].s;     for(i=1;i<=n;i++)          printf("%d\n",sx[i]);     return 0;}


0 0
原创粉丝点击