[BZOJ4237]稻草人 cdq分治+单调栈

4237: 稻草人

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 1340  Solved: 589
[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

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define ll long long
 8 using namespace std;
 9 struct data {
10     int x,y;
11 }a[200005],sta2[200005],sta1[200005];
12 int n;
13 bool cmp1(data t1,data t2) {return t1.x==t2.x?t1.y<t2.y:t1.x<t2.x;}
14 bool cmp2(data t1,data t2) {return t1.y==t2.y?t1.x<t2.x:t1.y<t2.y;}
15 ll ans=0,tot1,tot2;
16 void cdq(int l,int r) {
17     int mid=l+r>>1;
18     if(l==r) return;
19     cdq(l,mid);cdq(mid+1,r);
20     sort(a+l,a+mid+1,cmp2);
21     sort(a+mid+1,a+r+1,cmp2);
22     int tot1=tot2=0,now=l;
23     for(int i=mid+1;i<=r;i++) {
24         while(tot1&&sta1[tot1].x>=a[i].x) tot1--;
25         sta1[++tot1]=a[i];
26         while(now<=mid&&a[now].y<a[i].y) {
27             while(tot2&&sta2[tot2].x<=a[now].x) tot2--;
28             sta2[++tot2]=a[now++];
29         }
30         ans+=(long long)(tot2-(lower_bound(sta2+1,sta2+tot2+1,sta1[tot1-1],cmp2)-sta2)+1);
31     }
32 }
33 int main() {
34     sta1[0]=sta2[0]=(data){-1,-1};
35     scanf("%d",&n);
36     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
37     sort(a+1,a+n+1,cmp1);
38     cdq(1,n);
39     printf("%lld\n",ans);
40 }
View Code

 

posted @ 2018-02-09 13:34  wls001  阅读(179)  评论(0编辑  收藏  举报