HDU-3308 LCIS(区间合并)

题目大意:给一个整数序列,m次询问,每次询问某个区间中最长连续上升子序列的长度。

题目分析:线段树区间合并。维护以区间左端开头的、以区间右端点结尾的和区间最长的上升连续序列。

 

代码如下:

# include<bits/stdc++.h>
using namespace std;
# define LL long long
# define mid (l+(r-l)/2)

const int N=100000;

int w[N+5];
int len[N*4+5];
int l1[N*4+5],l3[N*4+5];
int r1[N*4+5],r3[N*4+5];

void pushUp(int rt,int l,int r)
{
	len[rt]=0;
	if(w[mid]<w[mid+1]){
		if(r1[rt<<1]==mid) r1[rt]=r1[rt<<1|1];
		else r1[rt]=r1[rt<<1];
		if(l1[rt<<1|1]==mid+1) l1[rt]=l1[rt<<1];
		else l1[rt]=l1[rt<<1|1];
		
		if(r1[rt<<1|1]-l1[rt<<1]+1>len[rt]){
			len[rt]=r1[rt<<1|1]-l1[rt<<1]+1;
			l3[rt]=l1[rt<<1];
			r3[rt]=r1[rt<<1|1];
		}
	}else{
		l1[rt]=l1[rt<<1|1];
		r1[rt]=r1[rt<<1];
	}
	if(r1[rt]-l+1>len[rt]){
		len[rt]=r1[rt]-l+1;
		l3[rt]=l,r3[rt]=r1[rt];
	}
	if(r-l1[rt]+1>len[rt]){
		len[rt]=r-l1[rt]+1;
		l3[rt]=l1[rt],r3[rt]=r;
	}
	if(r3[rt<<1]-l3[rt<<1]+1>len[rt]){
		len[rt]=r3[rt<<1]-l3[rt<<1]+1;
		l3[rt]=l3[rt<<1];
		r3[rt]=r3[rt<<1];
	}
	if(r3[rt<<1|1]-l3[rt<<1|1]+1>len[rt]){
		len[rt]=r3[rt<<1|1]-l3[rt<<1|1]+1;
		l3[rt]=l3[rt<<1|1];
		r3[rt]=r3[rt<<1|1];
	}
}

void build(int rt,int l,int r)
{
	if(l==r){
		len[rt]=1;
		l1[rt]=r1[rt]=l;
		l3[rt]=r3[rt]=l;
	}else{
		build(rt<<1,l,mid);
		build(rt<<1|1,mid+1,r);
		pushUp(rt,l,r);
	}
}

void update(int rt,int l,int r,int p,int x)
{
	if(l==r){
		w[l]=x;
	}else{
		if(p<=mid) update(rt<<1,l,mid,p,x);
		if(p>mid) update(rt<<1|1,mid+1,r,p,x);
		pushUp(rt,l,r);
	}
}

int query(int rt,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)
		return len[rt];
	if(R<=mid) return query(rt<<1,l,mid,L,R);
	if(L>mid) return query(rt<<1|1,mid+1,r,L,R);
	int li=query(rt<<1,l,mid,L,R);
	int ri=query(rt<<1|1,mid+1,r,L,R);
	int res=max(li,ri);
	if(w[mid]<w[mid+1])
		res=max(res,min(R,r1[rt<<1|1])-max(L,l1[rt<<1])+1);
	return res;
}

int main()
{
	int T,n,m;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;++i) scanf("%d",w+i);
		
		build(1,0,n-1);
		int a,b;
		char op[2];
		while(m--)
		{
			scanf("%s%d%d",op,&a,&b);
			if(op[0]=='Q'){
				printf("%d\n",query(1,0,n-1,a,b));
			}else if(op[0]=='U')
				update(1,0,n-1,a,b);
		}
	}
	return 0;
}

  

posted @ 2016-08-02 15:29  20143605  阅读(238)  评论(0编辑  收藏  举报