列表

详情


NC53262. 稻草人

描述

题目译自 JOISC 2014 Day3 T2「かかし
JOI村有一片荒地,上面竖着N个稻草人。任意两个稻草人的横坐标都不相同,任意两个稻草人的纵坐标都不相同。村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
  •  田地的形状是边平行于坐标轴的长方形;
  • 左下角和右上角各有一个稻草人;
  • 田地的内部(不包括边界)没有稻草人
。给出每个稻草人的坐标,请你求出有多少个满足条件的田地。

输入描述

第一行一个正整数N,代表稻草人的个数。
接下来N行,第i行包含2个由空格分隔的整数X_iY_i,表示第i个稻草人的坐标。

输出描述

一行,一个整数,表示有多少个满足条件的田地。

示例1

输入:

4
0 0
2 2
3 4
4 3

输出:

3

说明:

所有满足要求的田地如下图所示:

示例2

输入:

10
2 1
3 0
6 3
10 2
16 4
0 8
8 12
11 14
14 11
18 10

输出:

15

说明:

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 410ms, 内存消耗: 2424K, 提交时间: 2019-10-24 17:49:59

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=200010;
inline const int read(){
   register int f=1,x=0;
   register char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
   while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
   return f*x;
}
struct point{
   int x,y;
}aa[maxn];
long long ans;
int s1[maxn],s2[maxn],n;
inline bool cmpx(point a,point b){return a.x<b.x;}
inline bool cmpy(point a,point b){return a.y<b.y;}
void cdqz(int lf,int rg){
   if(lf==rg) return;
   int mid=(lf+rg)>>1,j=lf,top1=0,top2=0;
   cdqz(lf,mid),cdqz(mid+1,rg);
   sort(aa+lf,aa+mid+1,cmpx),sort(aa+mid+1,aa+rg+1,cmpx);
   for(int i=mid+1;i<=rg;i++){
       while(top1&&aa[s1[top1]].y>=aa[i].y) top1--;
	   s1[++top1]=i;
	   while(aa[j].x<aa[i].x&&j<=mid){
	      while(top2&&aa[s2[top2]].y<=aa[j].y) top2--;
	      s2[++top2]=j;
	      j++;
	   }
	   int l=1,r=top2,std=aa[s1[top1-1]].x,pos=-1;
	   while(l<=r){
	       int mid=(l+r)>>1;
	       if(aa[s2[mid]].x>std) pos=mid,r=mid-1;
	       else l=mid+1;
	   }
	   if(pos!=-1) ans+=top2-pos+1; 
   }
}
int main(){
   n=read();
   aa[0].x=aa[0].y=-1;
   for(register int i=1;i<=n;i++) aa[i].x=read(),aa[i].y=read();
   sort(aa+1,aa+n+1,cmpy);
   cdqz(1,n);
   printf("%lld\n",ans);
}

上一题