[BZOJ] 3262: 陌上花开

CDQ分治

大排序降一维,分治降一维,权值树状数组解决一维。

#include<algorithm>
#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } int n,m; const int MAXN=300005; int t[MAXN]; inline void update(int x,int w){ for(int i=x;i<=m;i+=i&-i)t[i]+=w; } inline int query(int x){ int ret=0; for(int i=x;i;i-=i&-i)ret+=t[i]; return ret; } struct Node{ int x,y,z,w; int f; bool operator <(const Node &rhs)const{ return (x==rhs.x&&y==rhs.y)?z<rhs.z:(x==rhs.x)?y<rhs.y:x<rhs.x; } }a[MAXN],tmp[MAXN];

void CDQ(int l,int r){ if(l==r) return; int mid=l+r>>1; CDQ(l,mid);CDQ(mid+1,r); int i=l,j=mid+1,p=l; while(i<=mid||j<=r){ if(j>r||i<=mid&&a[i].y<=a[j].y) update(a[i].z,a[i].w),tmp[p++]=a[i++]; else a[j].f+=query(a[j].z),tmp[p++]=a[j++]; } for(i=l;i<=mid;i++) update(a[i].z,-a[i].w); for(i=l;i<=r;i++) a[i]=tmp[i]; } int ans[MAXN]; int main(){ n=rd();m=rd(); for(int i=1;i<=n;i++){ a[i].x=rd();a[i].y=rd();a[i].z=rd(); a[i].w=1; } sort(a+1,a+1+n); int p=1; for(int i=2;i<=n;i++){ if(a[i].x==a[p].x&&a[i].y==a[p].y&&a[i].z==a[p].z) a[p].w++; else a[++p]=a[i]; } int sav=n; n=p; CDQ(1,n); for(int i=1;i<=n;i++){ ans[a[i].f+a[i].w-1]+=a[i].w; } for(int i=0;i<=sav-1;i++) printf("%d\n",ans[i]); return 0; }

猜你喜欢

转载自www.cnblogs.com/ghostcai/p/9507894.html
今日推荐