zoukankan      html  css  js  c++  java
  • 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]);
    }
    
    
    	
    
  • 相关阅读:
    SaaS模式应用之多租户系统开发(单数据库多Schema设计)
    web-api POST body object always null
    linq to js 用法
    c#导出数据到csv文本文档中,数据前面的0不见了解决方法
    金蝶BOS元模型分析
    DotNet 资源大全中文版
    JavaScript中的类方法、对象方法、原型方法
    解决System.Data.SqlClient.SqlException (0x80131904): Timeout 时间已到的问题
    在需要隐藏navigationController控制器
    升级macOS Sierra系统 导致错误 app: resource fork, Finder information, or similar detritus not allowed
  • 原文地址:https://www.cnblogs.com/nanke/p/2209462.html
Copyright © 2011-2022 走看看