【BZOJ4237】稻草人

Description

JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
田地的形状是边平行于坐标轴的长方形;
左下角和右上角各有一个稻草人;
田地的内部(不包括边界)没有稻草人。
给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数

Input

第一行一个正整数N,代表稻草人的个数
接下来N行,第i行(1<=i<=N)包含2个由空格分隔的整数Xi和Yi,表示第i个稻草人的坐标

Output

输出一行一个正整数,代表遵从启示的田地的个数

Sample Input

4
0 0
2 2
3 4
4 3

Sample Output

3

HINT

所有满足要求的田地由下图所示:
 
1<=N<=2*10^5
0<=Xi<=10^9(1<=i<=N)
0<=Yi<=10^9(1<=i<=N)
Xi(1<=i<=N)互不相同。

Yi(1<=i<=N)互不相同。

题解:这种题能否想到cdq分治是重点。

既然用cdq分治就一定要排序,那么怎么排呢?我们发现:第一维按x从小到大排序,第二位按y从大到小排序,可以便于我们进一步的处理。(反正就4种排序方法,自己挨个试一试就知道了~)

所以我们将所有点按x分治,左右两边分别按y从大到小排序,我们想找的就是左下角在[l,mid],右上角在[mid+1,r]中的矩形。发现,如果[l,mid]中的一个点i可以跟[mid+1,r]中的一些j1,j2...jk组成矩形,那么假设y[j1]>y[j2]>...>y[jk],一定满足x[j1]<x[j2]<..<x[jk]。反过来,每个j对应的i1,i2...ik也是有规律的。所以我们想到给左右两边都维护一个单调栈,那么思考该维护两个怎样的单调栈。

经过尝试发现(也就4种,一个一个试~),令左边的单调栈中的x单调递减,右边的x单调递增,可以便于我们进一步处理。我们对于[l,mid]中的i,设k是[l,mid]中满足x[k]>x[i],y[k]>y[i]且y值最小的点。那么i只能与[mid+1,r]中y值在[y[i],y[k]]中的点组成矩形。并且,如果这些点的y值递减,这些点的x值是递增的(也就是说都在单调栈里)。那么我们直接在右边的单调栈中二分统计一下y值符合条件的个数就行了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200010;
typedef long long ll;
ll ans;
int n,t1,t2;
int x[maxn],y[maxn],p[maxn],s1[maxn],s2[maxn];
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
bool cmpx(int a,int b)
{
return (x[a]==x[b])?(y[a]>y[b]):(x[a]<x[b]);
}
bool cmpy(int a,int b)
{
return (y[a]==y[b])?(x[a]<x[b]):(y[a]>y[b]);
}
void solve(int l,int r)
{
if(l==r) return ;
int i,j,mid=l+r>>1,last,L,R,MID;
sort(p+l,p+mid+1,cmpy),sort(p+mid+1,p+r+1,cmpy);
for(i=l,j=mid+1,t1=t2=0;i<=mid;i++)
{
for(;y[p[j]]>=y[p[i]]&&j<=r;j++)
{
while(t2&&x[s2[t2]]>x[p[j]]) t2--;
s2[++t2]=p[j];
}
while(t1&&x[s1[t1]]<x[p[i]]) t1--;
last=y[s1[t1]],s1[++t1]=p[i];
L=1,R=t2+1;
while(L<R)
{
MID=L+R>>1;
if(y[s2[MID]]<=last) R=MID;
else L=MID+1;
}
ans+=t2-R+1;
}
sort(p+l,p+r+1,cmpx);
solve(l,mid),solve(mid+1,r);
}
int main()
{
x[0]=0,y[0]=1<<30;
n=rd();
int i;
for(i=1;i<=n;i++) x[i]=rd(),y[i]=rd(),p[i]=i;
sort(p+1,p+n+1,cmpx);
solve(1,n);
printf("%lld",ans);
return 0;
}

【BZOJ4237】稻草人 cdq分治+单调栈+二分的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. $bzoj4237$稻草人 $cdq$分治

    正解:$cdq$分治 解题报告: 传送门$QwQ$ $umm$总感觉做过这题的亚子,,,? 先把坐标离散化,然后把所有点先按$x$排序$QwQ$,然后用类似平面最近点对的方法,先分别解决$mid$两侧 ...

  8. [BZOJ4237]稻草人(CDQ分治)

    先按y排序,二分,两边递归下去,然后处理下半部分对上半部分的贡献,即左下点在下半部分,右上点在上半部分的合法矩形个数. 两个部分均按x排序,枚举右上点p,则左下点需要满足: 1.横坐标大于上半部分纵坐 ...

  9. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

随机推荐

  1. Android 读取手机联系人、拨号、发送短信及长按菜单的操作

    本示例实现了读取手机联系人,拨号.发送短信及长按出现菜单选项的操作↓ 1.Andrid项目结构图↓主要操作图中红色方框内的文件. 2.首先布局代码如下↓ a, main.xml 程序运行的主界面,主要 ...

  2. mysql 更新数据

    set @num= 1000;update table set a= @num:=@num+1; set @date=now();UPDATE Orders t SET t.CreateTime = ...

  3. python 安装cx_Oracle模块, MySQLdb模块, Tornado

    一,想访问远程Oracle数据库,本地又不想安装几百兆的Oracle Client(也木有root权限),安装python的cx_Oralce 模块需要依赖Oracle Instant Client ...

  4. CSU 1997: Seating Arrangement【构造】

    1997: Seating Arrangement Description Mr. Teacher老师班上一共有n个同学,编号为1到n. 在上课的时候Mr. Teacher要求同学们从左至右按1, 2 ...

  5. BZOJ1858 [Scoi2010]序列操作(线段树)

    题目链接 [Scoi2010]序列操作 考验代码能力的一道好题. 思想还是很简单的(直接上线段树),但是比较难写. #include <bits/stdc++.h> using names ...

  6. SpringMVC+Shiro权限管理(转载)

    源码 http://pan.baidu.com/s/1pJzG4t1 SpringMVC+Shiro权限管理 博文目录 权限的简单描述 实例表结构及内容及POJO Shiro-pom.xml Shir ...

  7. ios内存管理笔记(二)

    1)实现部分: 复制代码 @synthesize window=_window; @synthesize viewController=_viewController; 通常看到的都没有包含=部分,@ ...

  8. mac下virtualenv使用

    1  sudo pip install virtualenv 安装 2 找一合适目录装虚拟环境 virtualenv virzhongguo 3  激活虚拟环境 source virzhongguo/ ...

  9. git-for-windows 安装无图标的问题

    git-for-windows.ico 安装无图标的问题 一. 问题表现: 桌面图标与右建菜单图标,所是未知文件的图标, 二. 问题解决: 在shard/git/ copy 一个ico 文件(如git ...

  10. Oracle 字段类型

    Oracle 字段类型 http://www.cnblogs.com/lihan/archive/2010/01/06/1640547.html 字段类型 描述 字段长度及其缺省值 CHAR (siz ...