bzoj 4237 稻草人 - CDQ分治 - 单调栈
考虑枚举左下角这个点。然后看一下是个什么情况:
嗯对,是个单调栈。但不可能暴力去求每个点右侧和上方的点的单调栈。
注意到如果给单调栈设个上界,那么顶多会削掉一些点,不会发生大的改变。
考虑CDQ分治,然后按照$y$从大到小排序。枚举左边的点然后不断把右边纵坐标大于它的点加入单调栈。(把横坐标比它大的全弹掉)
然后还需要考虑一个问题:
绿色点上方的点不能选。
如何找到这个上界?对左边开一个单调栈。然后在单调栈上二分。然后在右边的单调栈上二分可以找到有多少点不能选。
(今天考这道题,怀疑自己是zz,左边写一个线段树找上界,右边二分了两次)
Code
- /**
- * bzoj
- * Problem#4237
- * Accepted
- * Time: 7540ms
- * Memory: 8332k
- */
- #include <algorithm>
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <ctime>
- #ifndef WIN32
- #define Auto "%lld"
- #else
- #define Auto "%I64d"
- #endif
- using namespace std;
- typedef bool boolean;
- #define ll long long
- const signed int inf = (signed) (~0u >> );
- typedef class IO {
- public:
- int sta;
- }IO;
- int __tp = ;
- char __buf[];
- #define digit(_x) ((_x) >= '0' && (_x) <= '9')
- #define pick(_x) ((_x) = getchar())
- IO& operator >> (IO& io, int& u) {
- char x;
- while (~(x = getchar()) && !digit(x));
- for (u = x - ''; x = getchar(), digit(x); u = u * + x - '');
- return io;
- }
- IO in;
- template<typename T>
- void alloc(T*& p, int siz) {
- p = new T[(siz + )];
- }
- typedef class Point {
- public:
- int x, y;
- boolean operator < (Point b) const {
- if (y ^ b.y) return y > b.y;
- return x < b.x;
- }
- }Point;
- int n;
- ll res = ;
- int *buf;
- Point *ps, *bp;
- Point *pt, *vt;
- inline void init() {
- in >> n;
- alloc(vt, n);
- alloc(ps, n), alloc(bp, n);
- alloc(buf, n), alloc(pt, n);
- for (int i = ; i <= n; i++)
- in >> ps[i].x >> ps[i].y;
- }
- inline void discrete() {
- for (int i = ; i <= n; i++)
- buf[i] = ps[i].x;
- sort(buf + , buf + n + );
- for (int i = ; i <= n; i++)
- ps[i].x = lower_bound(buf + , buf + n + , ps[i].x) - buf;
- for (int i = ; i <= n; i++)
- buf[i] = ps[i].y;
- sort(buf + , buf + n + );
- for (int i = ; i <= n; i++)
- ps[i].y = lower_bound(buf + , buf + n + , ps[i].y) - buf;
- }
- int search(Point* pt, int tp, int y) {
- int l = , r = tp;
- while (l <= r) {
- int mid = (l + r) >> ;
- if (pt[mid].y <= y)
- r = mid - ;
- else
- l = mid + ;
- }
- return r + ;
- }
- void dividing(int l, int r, int ql, int qr) {
- if (l == r || ql > qr)
- return ;
- int mid = (l + r) >> ;
- int pl = l - , pr = r + ;
- for (int i = ql; i <= qr; i++)
- if (ps[i].x <= mid)
- bp[++pl] = ps[i];
- else
- bp[--pr] = ps[i];
- reverse(bp + pr, bp + qr + );
- for (int i = ql; i <= qr; i++)
- ps[i] = bp[i];
- int tp = , tp1 = ;
- vt[] = (Point) {inf, inf};
- for (int i = l; i <= pl; i++) {
- while (pr <= r && ps[pr].y > ps[i].y) {
- while (tp && pt[tp].x >= ps[pr].x)
- tp--;
- pt[++tp] = ps[pr], pr++;
- }
- int l = , r = tp1;
- while (l <= r) {
- int mid = (l + r) >> ;
- if (vt[mid].x >= ps[i].x)
- l = mid + ;
- else
- r = mid - ;
- }
- res += tp - search(pt, tp, vt[l - ].y) + ;
- while (tp1 && vt[tp1].x <= ps[i].x)
- tp1--;
- vt[++tp1] = ps[i];
- }
- dividing(l, mid, ql, pl);
- dividing(mid + , r, pl + , qr);
- }
- inline void solve() {
- sort(ps + , ps + n + );
- dividing(, n, , n);
- printf(Auto, res);
- }
- int main() {
- init();
- discrete();
- solve();
- return ;
- }
bzoj 4237 稻草人 - CDQ分治 - 单调栈的更多相关文章
- 【BZOJ4237】 稻草人 CDQ分治+单调栈
## 题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下 ...
- bzoj 4237: 稻草人 -- CDQ分治
4237: 稻草人 Time Limit: 40 Sec Memory Limit: 256 MB Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行 ...
- bzoj4237: 稻草人 cdq分治 单调栈
目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...
- 【BZOJ4237】稻草人 cdq分治+单调栈+二分
[BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...
- [BZOJ4237]稻草人:CDQ分治+单调栈
分析 按\(y\)排序后CDQ分治,可以发现每个点可以影响的是\(x\)坐标的一段区间,可以使用扫描线+单调栈,在单调栈上二分即可解决,时间复杂度\(O(n \log^2 n)\). 通过归并排序可以 ...
- Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】
正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...
- bzoj 4237 稻草人 CDQ
稻草人 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1433 Solved: 626[Submit][Status][Discuss] Descr ...
- 【bzoj4237】稻草人 分治+单调栈+二分
题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
随机推荐
- struts2.0自定义类型转换
在Struts2.0框架中内置了类型转换器,可以很方便的实现在八大数据类型.Date类型之间的自动转换:此外也可以根据自己的需求自定义数据转换类.如下: 首先看一下项目工程中的目录 1.在新建的web ...
- oracle数据库数值类型
---恢复内容开始--- 内容摘自网络 Oracle的数值类型有int,number,float,decimal,numberic等. NUMBER类型 定义 定义格式NUMBER (prec ...
- 解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集
character-set-server/default-character-set:服务器字符集,默认情况下所采用的. character-set-database:数据库字符集. characte ...
- idea上更新文件到github上
1.不是最新文件,那么文件颜色就不一样.操作如下: 2.本地提交 .提交文件列表,提交说明,文件前后对比,确定了后就提交 3.推送到github. (1) (2)
- python pillow
https://www.cnblogs.com/morethink/p/8419151.html#%E7%9B%B4%E6%8E%A5%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA ...
- Vue系列之 => 全局,私有过滤器
私有过滤器也称局部过滤器 <script> // 全局过滤器 Vue.filter("datatime",function(timestr){ var tm = new ...
- 文件格式(图像 IO 14.3)
文件格式 图片加载性能取决于加载大图的时间和解压小图时间的权衡.很多苹果的文档都说PNG是iOS所有图片加载的最好格式.但这是极度误导的过时信息了. PNG图片使用的无损压缩算法可以比使用JPEG的图 ...
- 【Scala学习之一】 Scala基础语法
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...
- 【Hadoop学习之三】Hadoop全分布式安装
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop3.1.1 全分布式就是集群,注意配置主机名. ...
- Bodymovin:Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画
转自:https://www.cnblogs.com/zamhown/p/6688369.html 大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画 ...