USACO Milking Cows

题意:给定N个区间,求最后区间内最长连续区间的长度以及最长不覆盖的长度

分析:本来是可以直接暴力的,可是想练一下最近线段树到底做得怎么样了,所以就用线段树试了一下,哎,改了俩个多小时,终于出来了。

注意:对区间长度的概念还是……因为离散化之后区间长度的求法变了,所以再求半个区间长度的时候,出错了

/*
ID: nanke691
LANG: C++
TASK: milk2
*/
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string.h>
#define maxn 20000
using namespace std;
int lb[maxn*3],rb[maxn*3],len1[maxn*3],len2[maxn*3],cnt[maxn*3];
int lb1[maxn*3],rb1[maxn*3];
int map[maxn<<2];
//lb[]表示该区间内左边连续覆盖的长度,rb[]该区间内右边连续覆盖的长度,len1[]该区间内连续覆盖的长度;
//len2[],该区间内连续的空区间的长度,lb1[]该区间内左边连续不覆盖的长度,rb1[]该区间内右边连续不覆盖的长度
//cnt[]表示该区间是否被全部覆盖
struct seg
{
	int x,y;
}ss[maxn];
void build(int k,int s,int t)
{
	lb[k]=rb[k]=len1[k]=0;
	cnt[k]=0;	
	lb1[k]=rb1[k]=len2[k]=map[t+1]-map[s];
	if(s==t)
		return ;
	int kl=k<<1,kr=kl+1,mid=(s+t)>>1;
	build(kl,s,mid);
	build(kr,mid+1,t);
}
int Bin(int n,int key)
{
	int left=0,right=n-1;
	while(left<=right)
	{
		int mid=(left+right)>>1;
		if(map[mid]==key)
			return mid;
		if(map[mid]<key)
			left=mid+1;
		else right=mid-1;
	}
	return -1;
}
void PushUp(int k,int s,int t)
{
	int l=map[t+1]-map[s];
	int mid=(s+t)>>1;
	int ml=map[mid+1]-map[s];
		lb1[k]=lb1[k<<1];
		rb1[k]=rb1[k<<1|1];	
		lb[k]=lb[k<<1];
		rb[k]=rb[k<<1|1];
		if(lb1[k<<1]== ml)//左边空区间长度等于左儿子的整个区间长度
			lb1[k]+=lb1[k<<1|1];
		if(lb[k<<1]== ml)//下面类似
		    lb[k]+=lb[k<<1|1];
		if(rb1[k<<1|1]==l-ml)
			rb1[k]+=rb1[k<<1];
		if(rb[k<<1|1]==l-ml)
			rb[k]+=rb[k<<1];
		len2[k]=max(rb1[k<<1]+lb1[k<<1|1],max(len2[k<<1],len2[k<<1|1]));
		len1[k]=max(rb[k<<1]+lb[k<<1|1],max(len1[k<<1],len1[k<<1|1]));

}
void update(int k,int l,int r,int s,int t)
{
	if(l<=s && t<=r)
	{
		cnt[k]=1;
		lb[k]=rb[k]=len1[k]=map[t+1]-map[s];
		rb1[k]=lb1[k]=len2[k]=0;
		return ;
	}
	if(cnt[k]==1)
		return ;
	int kl=k<<1,kr=kl+1,mid=(s+t)>>1;
	if(l<=mid)
		update(kl,l,r,s,mid);
	if(r>mid)
		update(kr,l,r,mid+1,t);
	PushUp(k,s,t);
}
int main()
{
	int n,m,a,b;
	FILE *fin  = fopen ("milk2.in", "r");
    FILE *fout = fopen ("milk2.out", "w");
	fscanf(fin,"%d",&n);
	//scanf("%d",&n);
	m=0;
	for(int i=0;i<n;i++)
	{
		fscanf(fin,"%d %d",&ss[i].x,&ss[i].y);
		//scanf("%d %d",&ss[i].x,&ss[i].y);
		map[m++]=ss[i].x;
		map[m++]=ss[i].y;
	}
	sort(map,map+m);
	int k=1;
	for(int i=1;i<m;i++)
		if(map[i]!=map[i-1])
			map[k++]=map[i];
	build(1,0,k-2);
	for(int i=0;i<n;i++)
	{
		int l=Bin(k,ss[i].x);
		int r=Bin(k,ss[i].y)-1;
		if(l<=r)
			update(1,l,r,0,k-2);
	}
	fprintf(fout,"%d %d\n",len1[1],len2[1]);
//	printf("%d %d\n",len1[1],len2[1]);
}


	
posted @ 2011-10-12 22:36  枕边梦  阅读(205)  评论(0编辑  收藏  举报