Lock Her Up

题意描述

同样没有链接...。

Problem 2: Lock Her Up [Jan Kuipers, 2003]

Bessie has been bad again and Farmer John must punish her by locking her up for a while. On his pastures he has N (1 <= N <= 250,000) rectangular fences in which he can pen her. His fences don't overlap or touch, however any given fenced area might wholly contain one or more other areas.

He knows that Bessie is a very smart cow and good at escaping from her prison. Therefore he wants to put her within a pen that is surrounded by as many other pens as possible. Furthermore he wants to know how many of those 'good prisons' there exist on his pastures. Help him learn these numbers.

PROBLEM NAME: lock

INPUT FORMAT:

  • Line 1: A single line with the single integer, N

  • Lines 2..N+1: Each line contains four space-separated integers (respectively X1, Y1, X2 and Y2) that are the coordinates of the lower left and upper right corner of the fences. All coordinates are in the range 1..1,000,000,000 and both X1

SAMPLE INPUT (file lock.in):

4
1 1 16 16
6 6 11 13
7 7 9 12
3 3 10 5

OUTPUT FORMAT:

  • Line 1: Two space-separated integers: the maximal number of fences that can surround Bessie and how many such places have this property.

SAMPLE OUTPUT (file lock.out):

3 1

OUTPUT DETAILS:

The 3rd fence is surrounded by fence 1 and 2, so Bessie can be locked within 3 fences. There is only 1 such place.

给定平面内 \(n\) 个矩形的左下角和右上角坐标,每个矩形边界没有重叠或覆盖。

求被最多矩形圈住的矩形的被圈层数,以及这种矩形的数量。

算法分析

像极了扫描线,于是就过了...。

将每个矩形变为上下两条边,离散化后直接线段树维护即可。

线段树维护的信息是这个点所在的矩形数量,具体流程如下:

  1. 遇到一个矩形的上边时将 \([x_1,x_2]\) 区间加 \(1\)
  2. 遇到一个矩形的下边时查询点 \(x_1\) 的值并更新答案。
  3. 再将 \([x_1,x_2]\) 区间减 \(1\)

具体看代码吧。

代码实现

#include
#include
#include
#include
#include
#define N 500010
using namespace std;

int n,ans=-1,num,cnt=0;
int tree[N<<2];
int X[N],Y[N];
struct node{
	int x1,x2,y,flag;
}p[N];

int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
	while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
	return x*f;
}

bool cmp(node a,node b){
	return a.y>1;
	if(x<=mid) return find(p<<1,l,mid,x);
	else return find(p<<1|1,mid+1,r,x);
}

void change(int p,int L,int R,int l,int r,int x){
	if(l<=L && R<=r){tree[p]+=x;return;}
	int mid=(L+R)>>1;
	if(tree[p]) tree[p<<1]=tree[p<<1|1]=tree[p],tree[p]=0;
	if(l<=mid) change(p<<1,L,mid,l,r,x);
	if(r>mid) change(p<<1|1,mid+1,R,l,r,x);
	return;
}

int main(){
	//freopen("lock.in","r",stdin);
	//freopen("lock.out","w",stdout);
	n=read();
	int x1,y1,x2,y2;
	for(int i=1;i<=n;i++){
		x1=read(),y1=read(),x2=read(),y2=read();
		p[++cnt].x1=x1;p[cnt].x2=x2;p[cnt].y=y1;p[cnt].flag=1;X[cnt]=x1;Y[cnt]=y1;
		p[++cnt].x1=x1;p[cnt].x2=x2;p[cnt].y=y2;p[cnt].flag=-1;X[cnt]=x2;Y[cnt]=y2;
	}
	sort(X+1,X+cnt+1);
	sort(Y+1,Y+cnt+1);
	int mx=unique(X+1,X+cnt+1)-(X+1);
	int my=unique(Y+1,Y+cnt+1)-(Y+1);
	for(int i=1;i<=cnt;i++){
		int px1=lower_bound(X+1,X+mx+1,p[i].x1)-X;
		int px2=lower_bound(X+1,X+mx+1,p[i].x2)-X; 
		int py=lower_bound(Y+1,Y+my+1,p[i].y)-Y;
		p[i].x1=px1;p[i].x2=px2;p[i].y=py;
	}
	sort(p+1,p+cnt+1,cmp);
    //上面是离散化。
	for(int i=1;i<=cnt;i++){
		if(p[i].flag==-1){
			int now=find(1,1,cnt,p[i].x1);//查询点 x1 的值。 
			if(now>ans)
				ans=now,num=1;
			else if(now==ans)
				num++;
		}
		change(1,1,cnt,p[i].x1,p[i].x2,p[i].flag);//区间加/减 1。
	}
	printf("%d %d\n",ans,num);
	//fclose(stdin);fclose(stdout);
	return 0;
}

完结撒花。

你可能感兴趣的:(Lock Her Up)