CDQ分治--模板 BZOJ 3262--陌上花开【三维偏序】
来源:互联网 发布:java类的主方法是啥 编辑:程序博客网 时间:2024/05/22 06:30
Description
有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
题解
这是典型的三维偏序的问题,可以套高级数据结构,当然,更简便的做法是用CDQ分治。
什么是CDQ分治
CDQ分治是陈丹琦大神(Orz%%%)在08提出来的,所以就叫CDQ分治。
我们知道,有一些动态修改的问题,需要各种数据结构,如果没有强制在线的话,就可以用CDQ分治将其转化成静态的问题。
CDQ分治是对操作序列分治:
1.将序列[l,r]分成两半[l,mid]和[mid+1,r];
2.分别处理两半序列中的操作;
3.考虑[l,mid]对[mid+1,r]的影响;
以此题为例
考虑如果是二维偏序我们怎么做?肯定是按照其中一维排序,剩下的交给树状数组,所以三位偏序也一样,先按其中一维排序,然后剩下的交给树套树(不会啊),但是我们不想写树套树,所以就用CDQ分治来处理剩下的两维。
考虑到既然已经按照x排过序了,那么前半段序列中的x一定
代码
#include<cstdio>#include<cstring>#include<algorithm>#define maxn 100006#define maxm 200006#define lowbit(x) (x&-x)using namespace std;inline char nc(){ static char buf[100000],*i=buf,*j=buf; return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;}inline int _read(){ char ch=nc();int sum=0; while(!(ch>='0'&&ch<='9'))ch=nc(); while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc(); return sum;}struct point{ int x,y,z,p; bool operator ==(const point&b)const{return x==b.x&&y==b.y&&z==b.z;} bool operator <(const point&b)const{return y<b.y||(y==b.y&&z<b.z);}}a[maxn],c[maxn];int n,m,ans[maxn],opt[maxm];bool cmp(point x,point y){return x.x<y.x||(x.x==y.x&&(x.y<y.y||(x.y==y.y&&x.z<y.z)));}void put(int x,int y){for(;x<=m;x+=lowbit(x))opt[x]+=y;}int get(int x){ int sum=0; for(;x;x-=lowbit(x))sum+=opt[x]; return sum;}void clear(int x){for(;x<=m;x+=lowbit(x))opt[x]=0;}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; for(int j=mid+1;j<=r;j++){ while(i<=mid&&a[i].y<=a[j].y)put(a[i].z,1),i++; a[j].p+=get(a[j].z); } for(int i=l;i<=mid;i++)clear(a[i].z); for(int i=l;i<=r;i++)c[i]=a[i]; i=l;int j=mid+1; for(int k=l;k<=r;k++) if(j>r||((i<=mid&&c[i]<c[j])))a[k]=c[i++]; else a[k]=c[j++];}int main(){ freopen("cdq.in","r",stdin); freopen("cdq.out","w",stdout); n=_read();m=_read(); for(int i=1;i<=n;i++) a[i].x=_read(),a[i].y=_read(),a[i].z=_read(); sort(a+1,a+1+n,cmp); cdq(1,n); sort(a+1,a+1+n,cmp); int i=1; while(i<=n){ int j=i,Max=0; while(j<=n&&a[i]==a[j])Max=max(Max,a[j++].p); ans[Max]+=j-i;i=j; } for(int i=0;i<n;i++)printf("%d\n",ans[i]); return 0;}
阅读全文
0 0
- CDQ分治--模板 BZOJ 3262--陌上花开【三维偏序】
- BZOJ 3262 陌上花开 CDQ分治 模板题
- [bzoj3262]陌上花开 三维偏序 cdq分治+树状数组
- bzoj3262陌上花开 cdq分治 三维偏序
- CDQ分治 陌上花开(三维偏序)
- BZOJ 3262 陌上花开、HDU 5618 Jam's problem again(三维偏序、cdq分治 + BIT)
- BZOJ 3262 陌上花开 CDQ分治
- BZOJ 3262: 陌上花开 CDQ分治
- BZOJ 3262 陌上花开(CDQ分治)
- bzoj 3262: 陌上花开 【cdq分治】
- bzoj 3262: 陌上花开(cdq分治)
- bzoj 3262: 陌上花开 cdq分治
- bzoj 3262: 陌上花开 (cdq分治)
- BZOJ 3262 陌上花开 CDQ分治
- BZOJ 3262: 陌上花开 (CDQ分治)
- Bzoj 3262: 陌上花开(CDQ分治)
- BZOJ 3262 陌上花开 树套树 (CDQ分治)
- BZOJ 3262 陌上花开 (CDQ分治)
- Contains Duplicate II
- Java GC专家系列1:理解Java垃圾回收
- Android_Framework_WindowManagerService_总述
- Python 爬虫简单实战之CSDN
- Python初学笔记
- CDQ分治--模板 BZOJ 3262--陌上花开【三维偏序】
- bootstrap-markdown使用
- c#winform选择文件,文件夹,打开指定目录方法
- Android屏幕适配问题
- Android的数据存储之SharedPreference与文件File
- Array----- 120. Triangle(计算路径最小和)
- LeetCode 448. Find All Numbers Disappeared in an Array
- 前端、Vue.js和SVG的一些知识
- 实用的60个CSS代码片段