4237: 稻草人
Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 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
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 ",ans); 40 }