JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
田地的形状是边平行于坐标轴的长方形;
左下角和右上角各有一个稻草人;
田地的内部(不包括边界)没有稻草人。
给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数
标签:span tac for cstring script 分治 php output 部分
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define il inline
#define RG register
#define LL long long
#define maxx 200010
using namespace std;
struct point{int x,y;}e[maxx];
int n;int s1[maxx],s2[maxx];LL Ans;
bool comp(const point & a,const point & b){return a.y<b.y;}
bool Comp(const point & a,const point & b){return a.x<b.x;}
il void CDQ(int l,int r){
if(l>=r)return;
int mid=(l+r)>>1;
sort(e+l,e+r+1,comp);int top1=0,top2=0;CDQ(l,mid),CDQ(mid+1,r);
sort(e+l,e+mid+1,Comp),sort(e+mid+1,e+r+1,Comp);
for(RG int j=mid+1,i=l;j<=r;++j){
while(top1&&e[s1[top1]].y>=e[j].y)top1--;
s1[++top1]=j;
while(e[i].x<=e[s1[top1]].x&&i<=mid){
while(top2&&e[s2[top2]].y<e[i].y)top2--;
s2[++top2]=i,i++;
}
int Min=e[s1[top1-1]].x,L=1,R=top2,pos=-1;
while(L<=R){
int Mid=(L+R)>>1;
if(e[s2[Mid]].x>Min)pos=Mid,R=Mid-1;
else L=Mid+1;
}if(pos!=-1)Ans+=top2-pos+1;
}
}
il void work(){
scanf("%d",&n);e[0].x=e[0].y=-1;
for(RG int i=1;i<=n;++i)scanf("%d%d",&e[i].x,&e[i].y);
CDQ(1,n);printf("%lld",Ans);return ;
}
int main(){
work();
return 0;
}
标签:span tac for cstring script 分治 php output 部分
原文地址:http://www.cnblogs.com/zzmmm/p/7143783.html