天天看點

BZOJ 3262: 陌上花開

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=200000+200;

struct Node{
  
  int a,b,c;
  int num,level;
}node[maxn];

bool cmp(Node A,Node 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(Node A,Node B){
  
  if(A.b==B.b) return A.c<B.c;
  return A.b<B.b;
}

int tree[maxn],color[maxn];
int ans[maxn];
int type;
int n,k;
int tot;

inline int lowbit(int x){
  
  return x&(-x);
} 

void Add(int ind,int v){
  
  while(ind<=k){
    
    if(color[ind]!=type) tree[ind]=0;
    color[ind]=type;
    tree[ind]+=v;
    ind+=lowbit(ind);
  }
}

int getSum(int ind){
  
  int sum=0;
  while(ind>0){
    
    if(color[ind]==type) sum+=tree[ind];
    ind-=lowbit(ind);
  }
  return sum;
}


void CDQ(int l,int r){
  
  if(l==r) return ;
  int mid=(l+r)>>1;
  CDQ(l,mid);
  CDQ(mid+1,r);
  sort(node+l,node+mid+1,cmpcdq);
  sort(node+mid+1,node+r+1,cmpcdq);
  int i=l;
  int j=mid+1;
  type++;
  for(;j<=r;j++){
    
    for(;node[i].b<=node[j].b&&i<=mid;i++) Add(node[i].c,node[i].num);
    node[j].level+=getSum(node[j].c); 
  }
}

int main(){
  
  scanf("%d%d",&n,&k);
  for(int i=1;i<=n;i++){
    
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    node[i]=Node{a,b,c,1,0};
  }
  sort(node+1,node+n+1,cmp);
  tot=1;
  for(int i=2;i<=n;i++){
    
    if(node[i].a==node[tot].a&&node[i].b==node[tot].b&&node[i].c==node[tot].c) node[tot].num++;
    else node[++tot]=node[i];
  }
  CDQ(1,tot);
  for(int i=1;i<=tot;i++) ans[node[i].num+node[i].level-1]+=node[i].num;
  for(int i=0;i<n;i++) printf("%d\n",ans[i]);
}