HDU 3308 LCIS

题意:

给出一个长度为N(N <= 100000)的数列,然后是两种操作:
U A B: 将第A个数替换为B (下标从零开始)
Q A B: 输出区间[A, B]的最长连续递增子序列;

这里注意:操作数可为100000;如果单纯的用暴力的方法可定超时,这里只是区间的操作,那么我们可以用线段数来做;

我们知道在一个区间如果左区间的右值比右区间的左值小,那么这两个区间可以合并成一个区间,在与左区间的最大值和右区间的最大值做比较,找出最大值;

如果小于那么我们就直接可以把左区间的最大值和右区间的最大值做比较,找出最大值;

这里就要设立几个变量:
 l_value 区间的最大连续递增序列的左值;

r_value 区间的最大连续递增序列的右值; 
l_max   区间以左端点开始最大的连续递增序列的最多的个数;

r_max  区间以右端点开始最大的连续递增序列的最多的个数;

max  区间的最大连续递增的序列的个数;

View Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
class Node
{
public:
int l_value,r_value;
int l_max,r_max;
int l,r,max;
};
Node tree[400024];
int num[100024];
int Max( int a , int b )
{
return a>b? a:b;
}
Node Update( Node a ,Node b )
{
Node t;
t.l = a.l; t.r = b.r;
t.l_value = a.l_value;
t.r_value = b.r_value;
if( a.l_max==( a.r - a.l+1 )&&a.r_value < b.l_value )
t.l_max = a.l_max + b.l_max;
else
t.l_max = a.l_max;
if( b.r_max==( b.r - b.l+1 )&&a.r_value < b.l_value )
t.r_max = b.r_max + a.r_max;
else t.r_max = b.r_max;
if( a.r_value < b.l_value )
t.max = Max( Max( a.max ,b.max ),a.r_max + b.l_max );
else t.max = Max( a.max , b.max );
return t;
}
void Maketree( int l , int r, int cnt )
{
tree[cnt].l = l;
tree[cnt].r = r;
tree[cnt].l_value = num[l];
tree[cnt].r_value = num[r];
if( l == r )
{
tree[cnt].l_max = tree[cnt].r_max = tree[cnt].max = 1;
return ;
}
int mid = ( l + r )>>1;
Maketree( l , mid ,cnt*2 );
Maketree( mid + 1 , r , cnt*2+1);
tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );
}
void Change( int place ,int value, int cnt )
{
if( place == tree[cnt].l&&tree[cnt].r == place )
{
tree[cnt].r_value = tree[cnt].l_value = value;
return ;
}
int mid = ( tree[cnt].r + tree[cnt].l )>>1;
if( place > mid ) Change( place , value , cnt*2+1 );
else Change( place ,value , cnt*2 );
tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );
}
Node Query( int l , int r, int cnt )
{
if( l<=tree[cnt].l&&r>=tree[cnt].r )
return tree[cnt];
int mid = (tree[cnt].l + tree[cnt].r)>>1;
if( l > mid ) return Query( l , r , cnt*2+1 );
else if( r <= mid ) return Query( l ,r ,cnt *2 );
else
{
Node a,b;
a = Query( l , mid , cnt*2 );
b = Query( mid + 1, r ,cnt*2 + 1);
return Update( a ,b );
}
}
int main( )
{
int n,N,m,A,B;
char c[4];
while( scanf( "%d",&N )==1 )
{
while( N-- )
{
scanf( "%d%d",&n,&m );
for( int i = 0; i< n ;i++ )
scanf( "%d",&num[i] );
Maketree( 0 , n-1 , 1 );
for( int i = 0 ; i< m ; i++ )
{
scanf( "%s%d%d",c , &A ,&B );
if( c[0]=='U' )
{
Change( A , B , 1 );
}
else
{
Node t = Query( A , B ,1 );
printf( "%d\n",t.max );
}
}
}
}
return 0;
}

 

 

你可能感兴趣的:(HDU)