【BZOJ 3262】陌上开花 CDQ分治

来源:互联网 发布:交易员 知乎 编辑:程序博客网 时间:2024/06/10 16:19

不想说了,感觉自己是傻逼

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define maxn 200021using namespace std;int n,c[maxn],K,ans[maxn],z[maxn],cc[maxn],bl[maxn];void update(int x,int add){while(x<=K){c[x]+=add;x+=x&-x;}}int query(int x){int ans=0;while(x>0){ans+=c[x];x-=x&-x;}return ans;}struct ques{int x,y,z,id;bool operator<(const ques& b)const{if(z!=b.z)return z<b.z;if(x!=b.x)return x<b.x;return y<b.y;}}q[maxn],p[maxn];bool cmp(const ques& a,const ques& b){if(a.x!=b.x)return a.x<b.x;if(a.y!=b.y)return a.y<b.y;return a.z<b.z;}void solve(int l,int r){if(l>=r)return;for(int i=l;i<=r;i++)z[i]=q[i].x;sort(z+l,z+r+1);int mid=l+r>>1,x=z[mid];int t1=l,t2=mid+1,cnt=0,z=0;for(int i=l;i<=r;i++)if(q[i].x<x)z++;for(int i=l;i<=r;i++){if(q[i].x<x)p[t1]=q[i],bl[i]=t1++,z--;else if(q[i].x==x&&z+t1<=mid)p[t1]=q[i],bl[i]=t1++;else p[t2]=q[i],bl[i]=t2++;}for(int j,i=l;i<=r;i=j){cnt=0;for(j=i+1;j<=r;j++){if(q[j].x!=q[j-1].x||q[j].y!=q[j-1].y||q[j].z!=q[j-1].z)break;else if(q[j].x==x&&bl[j]>mid)cnt++;}if(j>i+1&&q[i].x==x&&bl[i]>mid)cnt++;for(int k=i;k<j;k++)if(q[k].x==x&&bl[k]<=mid)ans[q[k].id]+=cnt;}for(int i=l;i<=r;i++){if(bl[i]<=mid)update(q[i].y,1);else ans[q[i].id]+=query(q[i].y);}for(int i=l;i<=r;i++){if(bl[i]<=mid)update(q[i].y,-1);}for(int i=l;i<=r;i++){if(bl[i]>mid&&q[i].x==x)update(q[i].y,1);else if(q[i].x==x)ans[q[i].id]+=query(q[i].y);}for(int i=l;i<=r;i++){if(bl[i]>mid&&q[i].x==x)update(q[i].y,-1);}for(int i=l;i<=r;i++)q[i]=p[i];solve(l,mid),solve(mid+1,r);}int main(){scanf("%d%d",&n,&K);for(int i=1;i<=n;i++)scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z),q[i].id=i;sort(q+1,q+1+n);solve(1,n);for(int i=1;i<=n;i++)cc[ans[i]]++;for(int i=0;i<n;i++)printf("%d\n",cc[i]);return 0;}


0 0
原创粉丝点击