bzoj 4237 稻草人

来源:互联网 发布:pc蛋蛋牛人28算法 编辑:程序博客网 时间:2024/05/20 03:46

4237: 稻草人

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



【分析】

CDQ分治+单调栈+二分



【代码】

//bzoj 4237 稻草人#include<bits/stdc++.h>#define ll long long#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=200005;ll ans;int n,m,T,top1,top2;struct node {int x,y;} a[mxn],tmp[mxn],s1[mxn],s2[mxn]; inline bool comp(node u,node v){return u.y<v.y;}inline int find(int l,int r,int x){while(l<r){int mid=(l+r>>1)+1;if(x>s1[mid].x) l=mid;else r=mid-1;}return l;}inline void CDQ(int l,int r){if(l==r) return;int i,j,mid=l+r>>1,l1=l,l2=mid+1;CDQ(l,mid),CDQ(mid+1,r);top1=top2=0;for(l2=mid+1;l2<=r;l2++){while(top2 && a[l2].y<s2[top2].y) top2--;s2[++top2]=a[l2];for(l1;l1<=mid && a[l1].x<a[l2].x;l1++){while(top1 && a[l1].y>s1[top1].y) top1--;s1[++top1]=a[l1];}ans+=top1-find(0,top1,s2[top2-1].x);}l1=l,l2=mid+1;fo(i,l,r)  tmp[i]=((l1<=mid && a[l1].x<a[l2].x) || l2>r)?a[l1++]:a[l2++];fo(i,l,r) a[i]=tmp[i];}int main(){int i,j;scanf("%d",&n);fo(i,1,n)  scanf("%d%d",&a[i].x,&a[i].y);sort(a+1,a+n+1,comp);CDQ(1,n);printf("%lld\n",ans);return 0;}


原创粉丝点击