洛谷传送门

BZOJ 4237 稻草人


题意

在一个平面直角坐标系上给出\(n\)个点,

问有多少个点对\((i,j)\)满足\(x_i<x_j,y_i<y_j\),

而且对于\(n\)个点中的任意一点都不在以点\(i\)为左下角,

点\(j\)为右上角的矩形内部(不包括边界)


分析

如果没有下面的限制应该是一道二维偏序裸题,但是限制不好搞

考虑用CDQ分治,也就是倘若\([l\sim mid]\)和\([mid+1\sim r]\)的答案已经弄好,处理区间不同的情况

假设一开始以纵坐标升序排序,

处理完一个区间该区间就以横坐标升序排序,

那也就是能保证\([l\sim mid]\)的\(y\),

均不超过\([mid+1\sim r]\)的\(y\),

区间内部的\(x\)单调不降

枚举右上角的\(j\),左下角可以用双指针,

那就可以确定一段左下角区间,因为区间内部\(x\)单调不降,

所以\([l\sim mid]\)的\(y\)单调不升才能不互相影响,

显然可以用单调栈维护;

那怎样判断右上角有没有影响,

只要查找到\(i\)左边第一个比它纵坐标小的点\(k\)就可以了,

显然还是可以用单调栈

然后左下角单调栈可选择的范围就是\(x_k\leq x_t\leq x_i\)

可以用二分来求,时间复杂度\(O(nlog^2n)\)

注意AT1225 かかし答案需要换行 (我就说我怎么WA了)

还是手画一张图好理解上面的抽象描述


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=200011;
int st2[N],st1[N],n;
long long ans;
struct rec{int x,y;}a[N],b[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(rec x,rec y){return x.y<y.y;}
inline signed divid(int l,int r,int z){//二分<z的最大值
while (l<r){
rr int mid=(l+r+1)>>1;
if (a[st2[mid]].x<z) l=mid;
else r=mid-1;
}
return l;
}
inline void cdq(int l,int r){
if (l==r) return;
rr int mid=(l+r)>>1,T1=0,T2=0;
cdq(l,mid),cdq(mid+1,r);
for (rr int i=mid+1,j=l;i<=r;++i){
while (T1&&a[i].y<a[st1[T1]].y) --T1;//右上角单调不降
st1[++T1]=i;
for (;a[j].x<a[i].x&&j<=mid;++j){
while (T2&&a[j].y>a[st2[T2]].y) --T2;//左下角单调不升
st2[++T2]=j;
}
if (a[st2[T2]].x>=a[st1[T1-1]].x)
ans+=T2-divid(0,T2,a[st1[T1-1]].x);
}
rr int i1=l,j1=mid+1,T=0;
//归并排序模板
while (i1<=mid&&j1<=r)
if (a[i1].x<=a[j1].x) b[++T]=a[i1],++i1;
else b[++T]=a[j1],++j1;
while (i1<=mid) b[++T]=a[i1],++i1;
while (j1<=r) b[++T]=a[j1],++j1;
for (rr int i=1;i<=T;++i) a[l+i-1]=b[i];
}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i)
a[i]=(rec){iut(),iut()};
sort(a+1,a+1+n,cmp),cdq(1,n);
return !printf("%lld\n",ans);
}

#CDQ分治,单调栈,双指针#BZOJ 4237 稻草人 AT1225 かかし的更多相关文章

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

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

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

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

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

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

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

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

  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. BZOJ_1307_玩具_单调栈+双指针

    BZOJ_1307_玩具_单调栈+双指针 Description 小球球是个可爱的孩子,他喜欢玩具,另外小球球有个大大的柜子,里面放满了玩具,由于柜子太高了,每天小球球都会让妈妈从柜子上拿一些玩具放在 ...

  9. bzoj 4237: 稻草人 -- CDQ分治

    4237: 稻草人 Time Limit: 40 Sec  Memory Limit: 256 MB Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行 ...

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

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

随机推荐

  1. Redis原理再学习03:数据结构-链表 list

    链表list介绍 1. 链表list简介 链表(linked list)是一种基础数据结构,是一种线性表,但是不会按照线性表的顺序存储数据,而是在每一个节点里存到下一个节点的指针. 链表插入节点时是 ...

  2. 【Android 逆向】【攻防世界】easy-apk

    apk 安装到手机,随便输入点内容,提示错误 2. apk 拖入到jadx中看看 public class MainActivity extends AppCompatActivity { /* JA ...

  3. android:加载PDF几种方法汇总对比

    在安卓项目中,加载PDF文件,是一个比较常见的需求.又分为两大类, 1.加载网络PDF 2.加载一个本地静态PDF. 查阅资料,纵观网上在安卓中打开PDF的各种方式,大致可以分为以下几类, 1.直接使 ...

  4. OpenCV开发笔记(六十一):红胖子8分钟带你深入了解Shi-Tomasi角点检测(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  5. 【LeetCode二叉树#11】最大二叉树(构造二叉树)

    最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构 ...

  6. 【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数

    [友元] 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术 友元的目的就是让一个函数或者类 访问另一个类中私有成员 友元的关键字为 friend 友元的三种实现 全 ...

  7. Hello-FPGA CoaXPress 2.0 FPGA DEVICE IP Core Demo

    Hello-FPGA CoaXPress 2.0 Device FPGA IP Core Demo 1     说明 本手册针对Helllo-FPGA的CoaXPress 2.0 DEVICE FPG ...

  8. C#多线程(9):多阶段并行线程

    目录 前言 Barrier 类 属性和方法 示例 新的示例 说明 前言 这一篇,我们将学习用于实现并行任务.使得多个线程有序同步完成多个阶段的任务. 应用场景主要是控制 N 个线程(可随时增加或减少执 ...

  9. 使用秘籍|如何实现图数据库 NebulaGraph 的高效建模、快速导入、性能优化

    本文整理自 NebulaGraph PD 方扬在「NebulaGraph x KubeBlocks」meetup 上的演讲,主要包括以下内容: NebulaGraph 3.x 发展历程 NebulaG ...

  10. Java 构造器(构造方法)练习

    1 package com.bytezero.triangle; 2 3 public class TriAngle 4 { 5 //私有属性 6 private double base; //边长 ...