bzoj3262 陌上花开 cdq分治(入门)
思路:cdq分治处理偏序关系的模板题,主要就是学cdq分治吧,还在入门中。
代码其实也很好理解,记得树状数组操作的上限是 z的最大值,不是n的最大值,这个细节wa了好久。
#include<bits/stdc++.h> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=100010; struct node{ int x,y,z,id; node(){} node(int x,int y,int z,int id):x(x),y(y),z(z),id(id){} }a[maxn],b[maxn]; int ans[maxn],bit[maxn<<1],pr[maxn]; int n,k,maxd; inline void add(int x,int v){ while(x<=maxd){//切记 上限不是n,是z的最大值 bit[x]+=v; x+= x & -x; } } inline int sum(int x){ int ces=0; while(x>0){ ces+=bit[x]; x -= x & -x; } return ces; } bool cmpall(const node &a,const node &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; } bool cmpy(const node &a,const node &b){ if(a.y!=b.y)return a.y<b.y; return a.id<b.id; } inline void cdq(int l,int r){ if(l==r)return ; int mid=(l+r)>>1; int cc=0; for(int i=l;i<=mid;i++) { b[++cc]=a[i]; b[cc].id=0,b[cc].x=0; } for(int i=mid+1;i<=r;i++) { b[++cc]=a[i],b[cc].x=0; } sort(b+1,b+1+cc,cmpy); for(int i=1;i<=cc;i++) { if(b[i].id==0){ add(b[i].z,1); }else{ ans[b[i].id]+=sum(b[i].z); } } for(int i=1;i<=cc;i++) { if(b[i].id==0)add(b[i].z,-1); } cdq(l,mid),cdq(mid+1,r); return ; } int main(){ cin>>n>>k; for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); maxd=max(maxd,a[i].z); a[i].id=i; } sort(a+1,a+1+n,cmpall); int cnt=0; for(int i=n;i>=1;i--) { if(a[i].x==a[i+1].x&&a[i].y==a[i+1].y&&a[i].z==a[i+1].z) { cnt++; }else cnt=0; ans[a[i].id]+=cnt; } cdq(1,n); for(int i=1;i<=n;i++) { pr[ans[i]]++; } for(int i=0;i<n;i++) { printf("%d\n",pr[i]); } }
——愿为泰山而不骄
qq850874665~~