BZOJ4237:稻草人 (CDQ分治+二分+单调栈)
来源:互联网 发布:手机知乎如何关注话题 编辑:程序博客网 时间:2024/05/29 03:52
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4237
题目分析:“有些题目,只要往二分答案那方面去想,就莫名其妙地变成了水题。”——by 龙神
现在我也想说,有些题目,只要往CDQ分治上去想,就莫名其妙变成了水题。这道题一开始看上去各种不可做,于是我们考虑先降一维,将所有点按X排序,然后将其分成左右两半,考虑左下角的点在左半部分,右上角的点在右半部分的矩形有几个:
如上图,我们将这些点按Y值从大到小做,遇到一个左边的点i时,我们需要知道从下往上第一个X值比它大的左边的点j是哪个,对此我们可以维护一个X值单调递减的栈,将点i加进来后不断弹出在它前面的X值比它小的点。同时我们要维护右半部分一个X值单调递增的栈(类似单调队列),然后统计右边的栈中有多少个点的Y值介于Y[j]~Y[i]之间。当点i作为矩形的左下角时,这些点便可作为矩形的右上角。这样时间复杂度为
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;const int oo=1e9+7;struct data{ int X,Y; bool Left;} point[maxn];int lsak[maxn];int rsak[maxn];int lc,rc;int n;long long ans=0;bool Comp1(data x,data y){ return x.X<y.X;}bool Comp2(data x,data y){ return x.Y>y.Y;}int Binary(int v){ rsak[rc+1]=n+1; int L=0,R=rc+1; while (L+1<R) { int mid=(L+R)>>1; if ( point[ rsak[mid] ].Y>v ) L=mid; else R=mid; } return L;}void CDQ(int l,int r){ if (l==r) return; int mid=(l+r)>>1; for (int i=l; i<=mid; i++) point[i].Left=true; sort(point+l,point+r+1,Comp2); lc=rc=0; for (int i=l; i<=r; i++) if (point[i].Left) { lsak[++lc]=i; while (lc>1&&point[ lsak[lc] ].X>point[ lsak[lc-1] ].X) lc--,lsak[lc]=lsak[lc+1]; if (lc==1) ans+=(long long)rc; else ans+=(long long)(rc- Binary(point[ lsak[lc-1] ].Y) ); } else { rsak[++rc]=i; while (rc>1&&point[ rsak[rc-1] ].X>point[ rsak[rc] ].X) rc--,rsak[rc]=rsak[rc+1]; } sort(point+l,point+r+1,Comp1); for (int i=l; i<=mid; i++) point[i].Left=false; CDQ(l,mid); CDQ(mid+1,r);}int main(){ freopen("4237.in","r",stdin); freopen("4237.out","w",stdout); scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%d%d",&point[i].X,&point[i].Y); sort(point+1,point+n+1,Comp1); point[0].Y=oo; point[n+1].Y=-1; CDQ(1,n); printf("%lld\n",ans); return 0;}
阅读全文
1 0
- [BZOJ4237]稻草人(cdq分治+单调栈+二分)
- BZOJ4237:稻草人 (CDQ分治+二分+单调栈)
- bzoj4237稻草人 cdq分治+栈
- BZOJ4237(cdq分治+单调栈)
- bzoj 4237: 稻草人 cdq分治+单调栈+二分
- 【bzoj4237】【分治】稻草人
- 【分治计数】BZOJ4237 稻草人
- [ CDQ分治 ] BZOJ4237
- [分治 单调栈] BZOJ 4237 稻草人
- bzoj 4237: 稻草人 CDQ分治
- [BZOJ 4237]稻草人:CDQ分治
- [bzoj4237]稻草人
- BZOJ4237: 稻草人
- bzoj4237: 稻草人
- BZOJ4237 稻草人
- BZOJ4237 稻草人
- [BZOJ]4237 稻草人 CDQ分治 详细题解
- CDQ分治&&整体二分
- Pythpn 爬虫爬取某宝商品数据
- ARKit 根据手指点击到屏幕上得点 获取真实空间中的坐标
- C语言中自带的头文件(.h)所包含的函数
- HDU4815Little Tiger vs. Deep Monkey(01背包)
- publish over cifs实现windows远程部署
- BZOJ4237:稻草人 (CDQ分治+二分+单调栈)
- 2017年8月10号提高组T2 飞行
- C# 字符分割与出现次数统计
- 浅谈 EF CORE 迁移和实例化的几种方式
- layui通用单图上传的方法
- 微信屏蔽朋友圈、分享给朋友、隐藏“传播类”和“保护类”按钮 不引weixin.js
- epoll和select的区别
- ART Dalvik
- 好玩的线上检测代码工具-codewars(3)