您的位置:首页 > 其它

USACO Milking Cows

2011-10-12 22:36 267 查看
题意:给定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]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: