线段树区间合并(POJ 3667 Hotel ,HDU HDU3308 LCIS)

对于线段树的合并,需要建立左右区间的ans,和整个区间的ans。

LCIS只需要更新就行,二hotel则要用到区间的更新和合并。

LCIS:

//#define zhouV
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<set>
#include<vector> 
using namespace std;
#define LL long long int  
const int  maxn= 100000;
struct ss
{
	int l,r,lb,rb,c;
	int lcis,rcis,mcis;
}T[4*maxn]; 
void Push_up(int id)
{
	int temp=id<<1;
	T[id].lcis=T[temp].lcis;
	T[id].rcis=T[temp+1].rcis;
	T[id].lb=T[temp].lb;
	T[id].rb=T[temp+1].rb;
	T[id].mcis=max(	T[temp].mcis,T[temp+1].mcis) ;
	if(T[temp].rb<T[temp+1].lb)
	{
		if(T[temp].c==T[temp].lcis)  T[id].lcis+=T[temp+1].lcis;
		if(T[temp+1].rcis==T[temp+1].c) T[id].rcis+=T[temp].rcis;
		T[id].mcis=max(T[id].mcis,T[temp].rcis+T[temp+1].lcis) ;	
	}
}

void build(int id,int l,int r)
{
	T[id].l=l;
	T[id].r=r;
	T[id].c=r-l+1;
	if(l==r)
	{
	   scanf("%d",&T[id].rb);
    
	  
	   T[id].lb=T[id].rb;
	   T[id].lcis=T[id].mcis=T[id].rcis=1;
	   return ;
	}
	int mid=(l+r)>>1;
	build(2*id,l,mid);
	build(2*id+1,mid+1,r);
	Push_up(id);
}
void inset(int id,int x,int v)
{
	if(T[id].l==T[id].r)
	{
		 T[id].lb=T[id].rb=v;
	
		 return ;
	}
	int mid=(T[id].l+T[id].r)>>1;
	if(x<=mid) inset(2*id,x,v);
	else inset(2*id+1,x,v);
	Push_up(id);	
}

int query(int id,int l,int r)
{
	if(T[id].l>=l  &&  T[id].r<=r)
	{
		return T[id].mcis;
	}
	int mid=(T[id].l+T[id].r)>>1;
	int ans=0;
	if(l<=mid) ans=max(ans,query(2*id,l,r));
	if(r>mid) ans=max(ans,query(2*id+1,l,r));
	if(T[2*id].rb<T[2*id+1].lb)
	{
		ans=max(ans,min(mid-l+1,T[2*id].rcis)+min(r-mid,T[2*id+1].lcis));
		 
	}
	return ans;  
}
int  main() 
{
	#ifdef zhouV
	freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	#endif
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,a,b;
		char s[5];
		scanf("%d%d",&n,&m);
		build(1,1,n);
		while(m--)
		{
           scanf("%s",s);
           scanf("%d%d",&a,&b);
           if(s[0]=='U')
           {
		        inset(1,a+1,b);
		        
		   }
		   else printf("%d\n",query(1,a+1,b+1));
           
           
		}
	}
	
	
}


hotel:

//#define zhouV
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long int
const int maxn=50010;
struct ss
{
    int l,r;
    int covert,lans,rans,mans;;
}T[4*maxn];
void push_up(int id)
{
    T[id].lans=T[id<<1].lans;
    T[id].rans=T[id<<1|1].rans;
	 T[id].mans=max(T[id].lans,T[id].rans);
    if(T[id<<1].lans==T[id<<1].r-T[id<<1].l+1)
    {
        T[id].lans+=T[id<<1|1].lans;
    }
     if(T[id<<1|1].rans==T[id<<1|1].r-T[id<<1|1].l+1)
     {
         T[id].rans+=T[id<<1].rans;
     }
     T[id].mans=max(T[id<<1].rans+T[id<<1|1].lans,max(T[id<<1].mans,T[id<<1|1].mans));
}

void build(int id,int l,int r)
{
   T[id].covert=-1;
   T[id].lans=T[id].mans=T[id].rans=r-l+1;
   T[id].l=l;
   T[id].r=r;
   if(l==r)
    {
         return;
    }
    int mid=(l+r)>>1;
    build(id<<1,l,mid);
    build(id<<1|1,mid+1,r);
}
void Push_down(int id)
{
    if(T[id].covert!=-1)
    {
        T[id<<1].covert=T[id<<1|1].covert=T[id].covert;
        if(T[id].covert)
        {
            T[id<<1].mans =T[id<<1].rans=T[id<<1].lans=0;
            T[id<<1|1].mans =T[id<<1|1].rans=T[id<<1|1].lans=0;
        }
        else
        {
           
            T[id<<1].mans =T[id<<1].rans=T[id<<1].lans=T[id<<1].r-T[id<<1].l+1;
            T[id<<1|1].mans =T[id<<1|1].rans=T[id<<1|1].lans=T[id<<1|1].r-T[id<<1|1].l+1;
        }
        T[id].covert=-1;
    }
}
void Up_data(int id,int l,int r,int v)
{

    if(T[id].l>=l&&T[id].r<=r)
    {           
        T[id].covert=v;
        if(v==0)
        {
           
           T[id].lans=T[id].mans=T[id].rans=T[id].r-T[id].l+1;
           T[id].covert=v;
        }
        else
        {
            T[id].lans=0;
            T[id].rans=0;
            T[id].mans=0;
            
        }
        return ;
    }
    Push_down(id);
    int mid=( T[id].r+T[id].l)>>1;
    if(l<=mid) Up_data(2*id,l,r,v);
    if(r>mid) Up_data(2*id+1,l,r,v);
    push_up(id);
}
int query(int id,int n)
{
    if(T[id].l==T[id].r) return T[id].l;
    Push_down(id);
    int mid=( T[id].r+T[id].l)>>1;
    if(T[id<<1].mans>=n) return query(id<<1, n);
    else if(T[id<<1].rans+T[id<<1|1].lans>=n) return mid-T[id<<1].rans+1;
    return query(2*id+1,n);
}
int main()
{
	#ifdef zhouV
	freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	#endif
	int n,m;
	cin>>n>>m;
	build(1,1,n);
	while(m--)
    {
        int a,b,c,f;
        scanf("%d",&a);
        if(a==1)
        {
            scanf("%d",&b);
            if(T[1].mans<b)
            {
                printf("0\n");
                continue;
            }
            else
            {
                f=query(1,b);
                printf("%d\n",f);
                Up_data(1,f,f+b-1,1);
            }

        }
        else
        {
            scanf("%d%d",&b,&c);
            Up_data(1,b,b+c-1,0);

        }
    }

}


你可能感兴趣的:(线段树区间合并(POJ 3667 Hotel ,HDU HDU3308 LCIS))