BZOJ 3262: 陌上花开 cdq分治 树状数组
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3262: 陌上花开 cdq分治 树状数组相关的知识,希望对你有一定的参考价值。
https://www.lydsy.com/JudgeOnline/problem.php?id=3262
cdq分治板子题,一维排序,一维分治(cdq里的队列),一维数据结构(树状数组)。
学dp优化前来复习……以前好像写过这道题但是没写博客啊……在校oj上写的题都没怎么写博客,追悔莫及
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int maxn=100100; 8 int n,m; 9 struct nod{ 10 int x,y,z; 11 int cnt,ans; 12 }a[maxn]; 13 int t[maxn*2],num[maxn],tot=0; 14 bool mcmp1(nod aa,nod bb){ 15 if(aa.x<bb.x)return 1; 16 if(aa.x>bb.x)return 0; 17 if(aa.y<bb.y)return 1; 18 if(aa.y>bb.y)return 0; 19 if(aa.z<bb.z)return 1; 20 return 0; 21 } 22 bool mcmp2(nod aa,nod bb){ 23 if(aa.y<bb.y)return 1; 24 if(aa.y>bb.y)return 0; 25 if(aa.z<bb.z)return 1; 26 if(aa.z>bb.z)return 0; 27 if(aa.x<bb.x)return 1; 28 return 0; 29 } 30 inline void addsum(int x,int v){ 31 while(x<=m){ 32 t[x]+=v;x+=(x&-x); 33 }return; 34 } 35 inline int getsum(int x){ 36 int tsn=0; 37 while(x){ 38 tsn+=t[x];x-=(x&-x); 39 }return tsn; 40 } 41 void mcdq(int l,int r){ 42 if(l==r){ 43 a[l].ans+=a[l].cnt-1; return; 44 } 45 int mid=(l+r)/2; 46 mcdq(l,mid);mcdq(mid+1,r); 47 sort(a+l,a+mid+1,mcmp2); 48 sort(a+mid+1,a+r+1,mcmp2); 49 int j=l; 50 for(int i=mid+1;i<=r;++i){ 51 while(j<=mid&&a[j].y<=a[i].y){addsum(a[j].z,a[j].cnt);++j;} 52 a[i].ans+=getsum(a[i].z); 53 } 54 for(int i=l;i<j;++i)addsum(a[i].z,-a[i].cnt); 55 } 56 int main(){ 57 scanf("%d%d",&n,&m); 58 for(int i=1;i<=n;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);a[i].ans=0;} 59 sort(a+1,a+1+n,mcmp1); 60 for(int i=1;i<=n;i++){ 61 if(i!=1&&a[i].x==a[i-1].x&&a[i].y==a[i-1].y&&a[i].z==a[i-1].z)a[tot].cnt++; 62 else {a[++tot]=a[i];a[tot].cnt=1;} 63 } 64 mcdq(1,tot); 65 for(int i=1;i<=tot;i++)num[a[i].ans]+=a[i].cnt; 66 for(int i=0;i<n;i++)printf("%d\n",num[i]); 67 return 0; 68 }
以上是关于BZOJ 3262: 陌上花开 cdq分治 树状数组的主要内容,如果未能解决你的问题,请参考以下文章