稻草人
Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1433 Solved: 626
[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)互不相同。
题解:这题就是就是统计问题,经典的CDQ,因为每个x,y都不同,好办得不行
按行分治,然后两边列排序,即可,维护一下,其实可以优化到n log n,外面可以预处理掉。
但是n log ^2n可以过
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 typedef long long LL; 9 const int MAXN = 200011; 10 int n,stack[MAXN],top,stack2[MAXN],tail; 11 LL ans; 12 struct node{ int x,y; }a[MAXN]; 13 inline bool cmpx(node q,node qq){ return q.x<qq.x; } 14 inline bool cmpy(node q,node qq){ return q.y<qq.y; } 15 inline int getint(){ 16 int w=0,q=0; char c=getchar(); while((c<‘0‘||c>‘9‘) && c!=‘-‘) c=getchar(); 17 if(c==‘-‘) q=1,c=getchar(); while (c>=‘0‘&&c<=‘9‘) w=w*10+c-‘0‘,c=getchar(); return q?-w:w; 18 } 19 20 inline void solve(int l,int r){ 21 if(l==r) return ; sort(a+l,a+r+1,cmpy); int mid=(l+r)>>1; 22 sort(a+l,a+mid+1,cmpx);//down 23 sort(a+mid+1,a+r+1,cmpx);//up 24 top=tail=0; int now=l,L,R,pos,mm,cp; 25 for(int i=mid+1;i<=r;i++) { 26 while(top>0 && a[stack[top]].y>=a[i].y) top--; 27 stack[++top]=i; 28 29 while(now<=mid && a[now].x<a[i].x) { 30 while(tail>0 && a[stack2[tail]].y<=a[now].y) tail--; 31 stack2[++tail]=now; 32 now++; 33 } 34 35 L=1; R=tail; pos=-1; cp=a[stack[top-1]].x; 36 while(L<=R) { 37 mm=(L+R)>>1; 38 if(a[stack2[mm]].x>cp) pos=mm,R=mm-1; 39 else L=mm+1; 40 } 41 if(pos!=-1) ans+=tail-pos+1; 42 } 43 solve(l,mid); solve(mid+1,r); 44 } 45 46 inline void work(){ 47 n=getint(); for(int i=1;i<=n;i++) a[i].x=getint(),a[i].y=getint(); 48 a[0].x=a[0].y=-1; 49 solve(1,n); 50 printf("%lld",ans); 51 } 52 53 int main() 54 { 55 work(); 56 return 0; 57 }