bzoj 4237: 稻草人(CDQ分治+单调栈+二分)
4237: 稻草人
Time Limit: 40 Sec Memory Limit: 256 MB
Submit: 1352 Solved: 594
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
所有点按y坐标排序之后进行CDQ分治,对于当前区间[L, R]过程如下图
①区间[L, mid]和区间(mid, R]先单独按x从小到大排序,
②对于区间[L, mid]维护一个纵坐标递减的单调栈s1,对于区间(mid, R]维护一个纵坐标递增的单调栈s2
对于栈s2,暴力枚举栈内相邻两个元素,在栈s1中二分出在这两个元素中间的点有多少个并加进答案
如上图,所有红点是当前在栈中的点,假设当前暴力到点a和b,那么就相当于在下面那个绿矩形中找出横坐标在点a和点b中间的点有多少个,结果显而易见为2个(红色矩阵中那两个点),ans += 2
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct Res
{int x, y;bool operator < (const Res &b) const{if(y<b.y)return 1;return 0;}
}Res;
Res s[200005], s1[200005], s2[200005];
LL ans;
int p[200005], q[200005];
bool comp(Res a, Res b)
{if(a.x<b.x)return 1;return 0;
}
void CDQ(int l, int r)
{int m, i, p, top, t2, L, R, mid;if(l==r)return;m = (l+r)/2;CDQ(l, m);CDQ(m+1, r);sort(s+l, s+m+1, comp);sort(s+m+1, s+r+1, comp);p = l, top = t2 = 0;s2[0].x = -10000;for(i=m+1;i<=r;i++){while(top>=1 && s1[top].y>s[i].y)top--;s1[++top] = s[i];while(p<=m && s[p].x<s[i].x){while(t2>=1 && s2[t2].y<s[p].y)t2--;s2[++t2] = s[p++];}L = 0, R = t2;while(L<R){mid = (L+R)/2;if(s2[mid].x<s1[top-1].x)L = mid+1;elseR = mid;}if(s2[R].x<s1[top-1].x)R++;ans += t2-R+1;}
}
int main(void)
{int n, i;scanf("%d", &n);for(i=1;i<=n;i++){scanf("%d%d", &s[i].x, &s[i].y);p[i] = s[i].x;}sort(p+1, p+n+1);for(i=1;i<=n;i++)s[i].x = lower_bound(p+1, p+n+1, s[i].x)-p;sort(s+1, s+n+1);CDQ(1, n);printf("%lld\n", ans);return 0;
}
/*
6
0 2
2 1
4 0
1 10
3 11
5 12
*/
bzoj 4237: 稻草人(CDQ分治+单调栈+二分)相关推荐
- Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】
正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的nnn个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 1≤n≤2×105,1≤ ...
- bzoj 4237: 稻草人 cdq分治
求有多少个点对 其一个点为左下角 一个点为右下角所形成的矩形内部没有点 每个x与y都不同 一开始的思路: 先按照x坐标排序 进行cdq分治 然后在cdq内对y进行排序 枚举mid+1-r的点作 ...
- BZOJ 2388--旅行规划(分块单调栈二分)
2388: 旅行规划 Time Limit: 50 Sec Memory Limit: 128 MB Submit: 405 Solved: 118 [Submit][Status][Discus ...
- CDQ 分治与整体二分
CDQ 分治与整体二分 CDQ 分治 主要是一种分治思想,常用于解决偏序问题. 例如三维偏序问题,我们采用的方法是先处理以第一关键字为区分的左区间.右区间内的答案,再处理左右区间互不干涉的答案. 四维 ...
- [CDQ分治与整体二分]个人对CDQ分治与整体二分的理解
在线/离线:首要考虑 在线算法: 可以以序列化的方式一个一个的处理输入,不必事先知道所有输入数据 离线算法: 必须事先知道所有的输入数据 (例如选择排序就是一个离线算法,而插入排序则不是) 众所周知, ...
- 【cdq分治】cdq分治与整体二分学习笔记Part1.整体二分
之所以把cdq分治和整体二分放在一起学习,是因为他们两个实在太像了-不管是做法还是代码- 感觉整体二分可能会比cdq分治稍微简单那么一点点?所以先学整体二分. 整体二分是对答案进行二分,其具体操作如下 ...
- cdq分治和整体二分
cdq分治 ps:先膜拜陈丹琦大神,Orz%%%. 作用 很多动态的题目都需要高级数据结构,代码量很大,这时候cdq分治就展现了它的强大.只要不强制在线,cdq分治就可以将动态转化为静态处理,而且代码 ...
- BZOJ4237 JOISC2014 稻草人 CDQ分治、单调栈
传送门 题意:给出平面上$N$个点,求满足以下两个条件的矩形:①左下角与右上角各有一个点:②矩形内部没有点.$N \leq 2 \times 10^5$,所有数字大于等于$0$,保证坐标两两不同 最开 ...
- AT1225 稻草人(cdq分治+二分)
题目链接 Link 思路分析 题目要求我们统计二维平面内的点所构成的不含其他点的矩形个数,因此想到 cdqcdqcdq 分治. 我们先按照横坐标递增排序,这样就只用考虑左下角在 [l,mid][l,m ...
最新文章
- java 注解报错_java注解验证接收参数 返回注解字段的错误
- Mocha BSM应用管理——Lotus Domino监控与管理
- bootstranp选项卡怎么把每个选项卡里面的表单分开提交_EXCEL 宏应用基础知识,利用已实现的宏,制作自己的功能选项卡...
- [C++基金会]位计算 游戏开发中的应用
- iframe中跨域页面访问parent的方法
- 欢迎使用CSDN-markdown编辑器12213123
- 给1-3年的前端 6 点诚心建议
- 你羡慕了吗?10万个数字人民币红包派发,每个200元
- Bootstrap+DataTables后端排序分页详解
- C/C++ Memory Layout
- oracle应用程序开发,关于Oracle 数据库应用程序开发问题
- CentOS-6.4 安装 Memcached
- linux服务器知识学习:linux系统的目录结构
- Drool的global变量
- 蓝墨云班课php答案,蓝墨云班课试题库答案
- 数据结构-左倾红黑树
- SpringBoot整合Redis + SpringCache + Protobuf,优雅地实现key-value键值对存储DEMO。
- adb连接网易mumu模拟器
- RichFaces第一例
- kali 镜像下载(免费下载)