您的位置:首页 > 其它

hdu 3308 LCIS (线段树)

2012-10-11 22:04 288 查看
线段树处理区间合并的问题。主要是记录一个区间包括左端点的最长的长度,包括右端点的最长的长度,整个区间的最长的长度,这三个信息。这样在合并两个区间时有足够的信息支持求出合并后区间最大的连续递增序列的长度。

查询时注意细节,特别是(a,b)分两段查询时,具体见代码。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAX 100010
using namespace std;
int A[MAX],L[4*MAX+1],R[4*MAX+1],len[4*MAX+1];

void build(int l,int r,int rt)
{
if( l==r )
{
len[rt]=L[rt]=R[rt]=1;
return ;
}
int m=(l+r)/2;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
if( A[m]<A[m+1])
{
if( L[rt<<1] == m-l+1 )
L[rt]=L[rt<<1]+L[rt<<1|1];
else
L[rt]=L[rt<<1];

if( R[rt<<1|1] == r-m )
R[rt]=R[rt<<1]+R[rt<<1|1];
else
R[rt]=R[rt<<1|1];

int LEN=R[rt<<1]+L[rt<<1|1];
len[rt]=max( max(len[rt<<1],len[rt<<1|1]),LEN );
}
else
{
L[rt]=L[rt<<1];  R[rt]=R[rt<<1|1];
len[rt]=max( len[rt<<1],len[rt<<1|1] );
}
}

void update(int pos,int l,int r,int rt)
{
if( l==r && l==pos )
{
len[rt]=L[rt]=R[rt]=1;
return ;
}
int m=(l+r)/2;
if( pos<=m ) update(pos,l,m,rt<<1);
else update(pos,m+1,r,rt<<1|1);
if( A[m]<A[m+1])
{
if( L[rt<<1] == m-l+1 )
L[rt]=L[rt<<1]+L[rt<<1|1];
else
L[rt]=L[rt<<1];

if( R[rt<<1|1] == r-m )
R[rt]=R[rt<<1]+R[rt<<1|1];
else
R[rt]=R[rt<<1|1];

int LEN=R[rt<<1]+L[rt<<1|1];
len[rt]=max( max(len[rt<<1],len[rt<<1|1]),LEN );
}
else
{
L[rt]=L[rt<<1];  R[rt]=R[rt<<1|1];
len[rt]=max( len[rt<<1],len[rt<<1|1] );
}
}

int query(int a,int b,int l,int r,int rt)
{
if(l==a && r==b)
{
return len[rt];
}
int m=(l+r)/2;
if( b<=m )  return query(a,b,l,m,rt<<1);
else
if( a>m ) return query(a,b,m+1,r,rt<<1|1);
else
{
int ans1=query(a,m,l,m,rt<<1);
int ans2=query(m+1,b,m+1,r,rt<<1|1);
if( A[m]<A[m+1] )
{
return max( max( min(R[rt<<1],m-a+1)+min(L[rt<<1|1],b-m),ans1),ans2 );
}
else

return max(ans1,ans2);
}
}

int main()
{
int n,m,i,j,t; char ch[10]; int a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",A+i);
build(1,n,1);
for(i=1;i<=m;i++)
{
scanf("%s",ch);
if( ch[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%d\n",query(a+1,b+1,1,n,1));
}else
{
scanf("%d%d",&a,&b);
A[a+1]=b;
update(a+1,1,n,1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: