bzoj 3262: 陌上花开

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define mid ((l+r)>>1) 
const int maxn=200005;
using namespace std;
int tot,n,k,a[maxn],b[maxn],ans[maxn],sg[maxn];
struct node{
  int a,b,c,d,rk;
}F[maxn],f[maxn];
bool cmp(const node &x,const node&y) { 
    return x.a==y.a?(x.b==y.b?x.c<y.c:x.b<y.b):x.a<y.a; 
}
bool CMP(const node &x,const node&y) {
    return x.b==y.b?x.c<y.c:x.b<y.b; 
}
void add (int x,int v) { 
    for(int i=x;i<=k;i+=(i&(-i))) a[i]+=v; 
} 
int sum(int x) { 
    int res=0; 
    for(int i=x;i>=1;i-=(i&(-i))) res+=a[i]; 
    return res;
}
bool chk(node x,node y ) { 
    return (x.a==y.a)&&(x.b==y.b)&&(x.c==y.c);
}
void cdq(int l,int r){
  if(l==r) {f[l].rk+=f[l].d-1; return;}
  cdq(l,mid); 
  cdq(mid+1,r);
  sort(f+l,f+mid+1,CMP); 
  sort(f+mid+1,f+r+1,CMP);
  int now=l;
  for(int i=mid+1;i<=r;f[i].rk+=sum(f[i].c),i++)
   for(int j=now;j<=mid&&f[j].b<=f[i].b;j++,now++) 
     add(f[j].c,f[j].d);
  for(int i=l;i<now;i++) add(f[i].c,-f[i].d);   
}
int main()
{
   scanf("%d%d",&n,&k);
   for(int i=1;i<=n;i++) {scanf("%d%d%d",&F[i].a,&F[i].b,&F[i].c); F[i].d=1;}
   sort(F+1,F+n+1,cmp);
   for(int i=1;i<=n;i++){
    if(chk(F[i],f[tot])) f[tot].d++;
    else f[++tot]=F[i]; 
   }
   cdq(1,tot);
   for(int i=1;i<=tot;i++) ans[f[i].rk]+=f[i].d;
   for(int i=0;i<n;i++) printf("%d\n",ans[i]);
   return 0;
}
CDQ分治

 

posted @ 2017-09-04 18:51  啊宸  阅读(117)  评论(0编辑  收藏  举报