标签 - 单调栈

单调栈 二分 分治    2016-10-19 23:34:03    190    0    5

4237: 稻草人

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 456  Solved: 191
[Submit][Status][Discuss]

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)互不相同。
 

Source

JOI 2013~2014 春季training合宿 竞技3 By PoPoQQQ

 

Solution

先将点按y轴排序,然后分治。

首先分治求出上下两块的答案,然后考虑左下角在下半部分,右上角在上半部分的答案

设左下角为(x1,y1),右上角为(x2,y2)

显然对于上部分有:对于所有横坐标在(x1,x2)的点,纵坐标≥y2

显然对于下部分有:对于所有横坐标在(x1,x2)的点,纵坐标≤y1

维护两个单调栈,枚举右上角,在单调栈上二分找符合条件的左下角即可

 

/*{{{*/
#include <bits/stdc++.h>

#define VAL(x) #x " = " << x << " "

#ifdef __linux__
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

st