传送门

题意:给出平面上$N$个点,求满足以下两个条件的矩形:①左下角与右上角各有一个点;②矩形内部没有点。$N \leq 2 \times 10^5$,所有数字大于等于$0$,保证坐标两两不同


最开始想到的是类似于楼房重建的算法,然后打炸了qwq

在多维问题上考虑分治可以降低一维限制,很多时候都会用到(比如三维偏序)。

我们先对$y$值从小到大排序,在分治内部对$x$值从小到大排序,然后考虑左边一半对右边的贡献。

可以知道对于左边一半的两个点$a,b(a<b)$,如果$y_a<y_b$,那么$a$会被$b$阻挡,就不会对答案产生贡献。所以我们可以维护一个$y$值递减的单调栈来保存可能对当前询问的点产生贡献的左边的点的集合,每一次询问下一个点时,把$x$值小于它的其他点加入单调栈即可。

接下来我们考虑右边的点对右边产生的影响(右边的某一些点阻挡了某一些左边的点产生贡献)。发现我们同样可以维护一个$y$值递增的单调栈来保存对当前点有影响的点的集合。每一次我们就取出栈顶的点,在左边的点对应的集合上二分,就可以得到它使多少个左边的点不产生贡献了。

 //This code is written by Itst
 #include<bits/stdc++.h>
 #define BZ
 #define mid ((l + r) >> 1)
 using namespace std;

 inline int read(){
     ;
     ;
     char c = getchar();
     while(c != EOF && !isdigit(c)){
         if(c == '-')
             f = ;
         c = getchar();
     }
     while(c != EOF && isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return f ? -a : a;
 }

 ;
 struct node{
     int x , y;
 }now[MAXN];
 int N , hd , Stack[MAXN] , Stack2[MAXN] , top;
 long long ans;

 bool cmp1(node a , node b){
     return a.y < b.y;
 }

 bool cmp2(node a , node b){
     return a.x < b.x;
 }

 inline int bis(int x){
      , R = hd;
     while(L < R){
          >> ;
         now[Stack[m]].x < x ? L = m : R = m - ;
     }
     return L;
 }

 void solve(int l , int r){
     if(l == r)
         return;
     solve(l , mid);
     solve(mid +  , r);
     ;
     hd = top = ;
     while(p2 <= r){
         while(top && now[Stack2[top]].y > now[p2].y)
             --top;
         Stack2[++top] = p2;
         while(p1 <= mid && now[p1].x < now[p2].x){
             while(hd && now[Stack[hd]].y < now[p1].y)
                 --hd;
             Stack[++hd] = p1++;
         }
         ans += hd - (top ==  ?  : bis(now[Stack2[top - ]].x));
         p2++;
     }
     sort(now + l , now + r +  , cmp2);
 }

 int main(){
 #ifdef BZ
     freopen("4237.in" , "r" , stdin);
     freopen("4237.out" , "w" , stdout);
 #endif
     N = read();
      ; i <= N ; i++){
         now[i].x = read();
         now[i].y = read();
     }
     sort(now +  , now + N +  , cmp1);
     solve( , N);
     cout << ans;
     ;
 }

BZOJ4237 JOISC2014 稻草人 CDQ分治、单调栈的更多相关文章

  1. 【BZOJ4237】 稻草人 CDQ分治+单调栈

    ## 题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下 ...

  2. 【BZOJ4237】稻草人 cdq分治+单调栈+二分

    [BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...

  3. bzoj4237: 稻草人 cdq分治 单调栈

    目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...

  4. bzoj 4237 稻草人 - CDQ分治 - 单调栈

    题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...

  5. [BZOJ4237]稻草人:CDQ分治+单调栈

    分析 按\(y\)排序后CDQ分治,可以发现每个点可以影响的是\(x\)坐标的一段区间,可以使用扫描线+单调栈,在单调栈上二分即可解决,时间复杂度\(O(n \log^2 n)\). 通过归并排序可以 ...

  6. Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】

    正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...

  7. 【bzoj4237】稻草人 分治+单调栈+二分

    题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...

  8. BZOJ4237 稻草人 分治 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/8682572.html 题目传送门 - BZOJ4237 题意 平面上有$n(n\leq 2\times 10^ ...

  9. 【BZOJ4237】稻草人 [分治][单调栈]

    稻草人 Time Limit: 40 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description JOI村有一片荒地,上面竖着N个稻草 ...

随机推荐

  1. React 入门学习笔记整理(九)——路由

    (1)安装路由 React-router React-router提供了一些router的核心api,包括Router, Route, Switch等,但是它没有提供dom操作进行跳转的api. Re ...

  2. 一个Web页面的问题分析

    几个月之前我接到一个新的开发任务,要在一个旧的Web页面上面增添一些新的功能.在开发的过程中发现旧的代码中有很多常见的不合适的写法,结合这些问题,如何写出更好的,更规范的,更可维护的代码,就是这篇文章 ...

  3. ios开发GCD(2)-dispatch_semaphore_t信号量计数器

    思考:现在有多个线程异步执行,我们想要同时最多只能执行2个或n个,该怎么办? dispatch_semaphore_t 看代码解析: NSLog(@"开始"); dispatch_ ...

  4. gitlab 和 github 配置 SSH Keys

    gitlab 文档上给了很好的配置的例子:https://gitlab.com/help/ssh/README#locating-an-existing-ssh-key-pair 针对mac 下的使用 ...

  5. fedora输入法

    fedora自带输入法,另外如果自己鼓捣的话很可能身心俱疲. 打开设置(在桌面右击也能打开) 区域和语言 在输入源中添加 汉语(中国) 快捷键 输入源切换:win+space 中英文切换:shift

  6. C# 动态方法和静态方法的区别

    C# 动态方法和静态方法的区别 (转) 动态方法与静态方法的区别: 1,使用方法上的区别:动态方法,在使用时需要先创建实例,才能调用实例方法,而静态方法则不需要,直接使用即可. 示例代码如下:静态方法 ...

  7. Linux 小知识翻译 - 「Shell」(也就是命令行接口)

    这次说说关于Shell的东西. 「Shell」是看不见实体的,所以理解起来可能会有些困难. 最近的Linux发行版默认都是用X Window System来操作的(也就是图形化操作),所以很少见到有人 ...

  8. jQuery插件slider实现图片轮播

    1:引入相应的js文件  jquery.SuperSilder.js 2:HTML: 结构 注:此地加载图片的代码也可以从后台库中读取图片的集合列表,然后通过循环的方式显示出来 3:CSS 样式定义左 ...

  9. 如何取得select结果数据集的前10条记录。postgresql

    我用的是POSTGRESQL.select name from t_personal order by personal_id desc 我想取得上面结果数据的,前10条记录.SQL语句怎么改. 我记 ...

  10. ajaxForm和ajaxSubmit 粘贴就可用

    <!--To change this template, choose Tools | Templatesand open the template in the editor.-->&l ...