BZOJ1790:[Ahoi2008]Rectangle 矩形藏宝地 (CDQ分治+线段树)
来源:互联网 发布:淘宝加盟骗局郑州 编辑:程序博客网 时间:2024/06/04 08:33
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1790
题目分析:这题我一开始想了很久,想到平面扫描啊乱七八糟的东西,后来发现其实我们根本不用当每一个藏宝地是一个矩形。如果一个藏宝地i的左下角坐标为(A,B),右上角坐标为(C,D),那么我们就是要查看有没有一个藏宝地的A值小于i的A值,而且其B值小于i的B值,其C,D值分别大于i的C,D值。这就是一个四位偏序嘛,而且我们只要判断有没有就可以了,所以是一个CDQ。于是我们先离散化,将藏宝地按A值排序,做CDQ分治;然后分治的时候按B值排序,作为时间戳插进以C的权值线段树里,并维护D的最大值即可。时间复杂度
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=200100;struct data{ int num; bool Left;} a[maxn];int tree[maxn<<2];int A[maxn];int B[maxn];int C[maxn];int D[maxn];int id[maxn];bool vis[maxn];int *R;int n;bool Comp1(int x,int y){ return R[x]<R[y];}void Work(){ for (int i=1; i<=n; i++) id[i]=i; sort(id+1,id+n+1,Comp1); for (int i=1; i<=n; i++) R[ id[i] ]=i;}bool Comp2(data x,data y){ return R[x.num]<R[y.num];}void Update(int root,int l,int r,int x,int v){ if ( x<l || r<x ) return; if ( l==x && x==r ) { tree[root]=v; return; } int mid=(l+r)>>1; int Left=root<<1; int Right=Left|1; Update(Left,l,mid,x,v); Update(Right,mid+1,r,x,v); tree[root]=max(tree[Left],tree[Right]);}int Query(int root,int l,int r,int x,int y){ if ( y<l || r<x ) return 0; if ( x<=l && r<=y ) return tree[root]; int mid=(l+r)>>1; int Left=root<<1; int Right=Left|1; int vl=Query(Left,l,mid,x,y); int vr=Query(Right,mid+1,r,x,y); return max(vl,vr);}void CDQ(int l,int r){ if (l==r) return; int mid=(l+r)>>1; for (int i=l; i<=mid; i++) a[i].Left=true; R=B; sort(a+l,a+r+1,Comp2); for (int i=l; i<=r; i++) if (a[i].Left) Update(1,1,n,C[ a[i].num ],D[ a[i].num ]); else if ( Query(1,1,n,C[ a[i].num ]+1,n)>D[ a[i].num ] ) vis[ a[i].num ]=true; for (int i=l; i<=r; i++) if (a[i].Left) Update(1,1,n,C[ a[i].num ],0); R=A; sort(a+l,a+r+1,Comp2); for (int i=l; i<=mid; i++) a[i].Left=false; CDQ(l,mid); CDQ(mid+1,r);}int main(){ freopen("1790.in","r",stdin); freopen("1790.out","w",stdout); scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%d%d%d%d",&A[i],&B[i],&C[i],&D[i]); R=B,Work(); R=C,Work(); R=D,Work(); R=A,Work(); for (int i=1; i<=n; i++) a[i].num=id[i]; CDQ(1,n); int ans=0; for (int i=1; i<=n; i++) if (vis[i]) ans++; printf("%d\n",ans); return 0;}
阅读全文
1 1
- BZOJ1790:[Ahoi2008]Rectangle 矩形藏宝地 (CDQ分治+线段树)
- [bzoj1790][Ahoi2008]Rectangle 矩形藏宝地
- BZOJ 1790: [Ahoi2008]Rectangle 矩形藏宝地(CDQ分治+离散化+线段树)
- bzoj 1790: [Ahoi2008]Rectangle 矩形藏宝地
- BZOJ 1790: [Ahoi2008]Rectangle 矩形藏宝地
- HDU6183 cdq分治+线段树
- hdu 6183 Color it(动态线段树,cdq分治)
- 【BZOJ2773】ispiti【CDQ分治】【线段树】
- COGS 577 蝗灾 线段树+CDQ分治
- 【线段树】【CDQ分治】回转寿司
- bzoj3295[Cqoi2011]动态逆序对(cdq分治||可持久化线段树)
- [BZOJ3295][Cqoi2011]动态逆序对(树状数组套线段树||cdq分治)
- 【bzoj 3110】【codevs 1616】K大数查询 (CDQ分治+线段树)
- HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)
- 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树
- HDU 6183 Color it [CDQ分治+线段树+位压缩]
- hdu 6183 Color it(cdq分治+线段树)
- 时间分治(cdq分治)
- U盘图标改成自己喜欢的图标
- BZOJ 1096: [ZJOI2007]仓库建设 斜率优化
- 2017-8-26 C#学习如何新建一个Helloworld
- 2017年8月26日 星期六
- 表、视图、实体化视图的比较
- BZOJ1790:[Ahoi2008]Rectangle 矩形藏宝地 (CDQ分治+线段树)
- IOS逆向笔记之HOOK实现(非越狱)
- 面试OR笔试11——集合交集
- PAT1038 Recover the Smallest Number (30)
- 性能指标(模型评估)之ROC与AUC
- 年总结
- c++引用
- 欢迎使用CSDN-markdown编辑器
- Dijkstra模板(优先队列)