裸的cdq,注意去重;
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=100010,maxm=200010; int tot,n,k,tr[maxm],h[maxn],t1,t2,len1,len2,ans[maxn]; void add(int pos,int v){ for(int i=pos;i<maxm;i+=i&(-i)) tr[i]+=v; } int qs(int pos){ int res=0; for(int i=pos;i;i-=i&(-i)) res+=tr[i]; return res; } struct node{ int ls,lc,lm,id,cnt; }tt[maxn],t[maxn],tmp1[maxn],tmp2[maxn]; int cmp1(node a,node b){ if(a.lm!=b.lm)return a.lm<b.lm; if(a.lc!=b.lc)return a.lc<b.lc; return a.ls<b.ls; } int cmp2(node a,node b){ if(a.lc!=b.lc)return a.lc<b.lc; return a.ls<b.ls; } void cdq(int l,int r){ if(l==r){ h[t[l].id]+=t[l].cnt-1; return; } int mid=l+r>>1; cdq(l,mid);cdq(mid+1,r); t1=t2=0; for(int i=l;i<=mid;++i)tmp1[++t1]=t[i]; for(int i=mid+1;i<=r;++i)tmp2[++t2]=t[i]; sort(tmp1+1,tmp1+t1+1,cmp2); sort(tmp2+1,tmp2+t2+1,cmp2); len1=t1,len2=t2; t1=t2=1; for(t2=1;t2<=len2;++t2){ while(tmp1[t1].lc<=tmp2[t2].lc&&t1<=len1){ add(tmp1[t1].ls,tmp1[t1].cnt);++t1; } h[tmp2[t2].id]+=qs(tmp2[t2].ls); } for(int i=1;i<t1;++i)add(tmp1[i].ls,-tmp1[i].cnt); } int main(){ cin>>n>>k; for(int i=1;i<=n;++i){ scanf("%d%d%d",&tt[i].ls,&tt[i].lc,&tt[i].lm); } sort(tt+1,tt+n+1,cmp1); for(int i=1;i<=n;++i){ if(i!=1&&tt[i-1].lm==tt[i].lm&&tt[i-1].ls==tt[i].ls&&tt[i-1].lc==tt[i].lc){ t[tot].cnt++; } else t[++tot]=tt[i],t[tot].cnt=1; } for(int i=1;i<=tot;++i)t[i].id=i; cdq(1,tot); for(int i=1;i<=tot;++i){ ans[h[i]]+=t[i].cnt; } for(int i=0;i<n;++i){ printf("%d\n",ans[i]); } system("pause"); return 0; }