HDU 3308 LCIS

求区间内最长连续上升子序列

线段树典型区间合并

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 #define lson l, m, rt << 1
  7 #define rson m + 1, r, rt << 1 | 1
  8 
  9 using namespace std;
 10 
 11 const int MAXN = 100010;
 12 
 13 int N, Q;
 14 int Lval[ MAXN << 2 ];
 15 int Rval[ MAXN << 2 ];
 16 int Llen[ MAXN << 2 ];
 17 int Rlen[ MAXN << 2 ];
 18 int maxLen[ MAXN << 2 ];
 19 
 20 void PushUp( int rt, int l, int r )
 21 {
 22     int lc = rt << 1;
 23     int rc = rt << 1 | 1;
 24 
 25     maxLen[rt] = max( maxLen[lc], maxLen[rc] );
 26     Lval[rt] = Lval[lc];
 27     Rval[rt] = Rval[rc];
 28     Llen[rt] = Llen[lc];
 29     Rlen[rt] = Rlen[rc];
 30 
 31     if ( Rval[lc] < Lval[rc] )
 32     {
 33         maxLen[rt] = max( maxLen[rt], Rlen[lc] + Llen[rc] );
 34 
 35         int m = ( l + r ) >> 1;
 36         if ( Llen[lc] == m - l + 1 )
 37             Llen[rt] += Llen[rc];
 38         if ( Rlen[rc] == r - m )
 39             Rlen[rt] += Rlen[lc];
 40     }
 41     return;
 42 }
 43 
 44 void build( int l, int r, int rt )
 45 {
 46     if ( l == r )
 47     {
 48         scanf( "%d", &Lval[rt] );
 49         Rval[rt] = Lval[rt];
 50         maxLen[rt] = Llen[rt] = Rlen[rt] = 1;
 51         return;
 52     }
 53 
 54     int m = ( l + r ) >> 1;
 55     build( lson );
 56     build( rson );
 57     PushUp( rt, l, r );
 58     return;
 59 }
 60 
 61 void Update( int L, int c, int l, int r, int rt )
 62 {
 63     if ( L == l && r == L )
 64     {
 65         Lval[rt] = c;
 66         Rval[rt] = c;
 67         return;
 68     }
 69 
 70     int m = ( l + r ) >> 1;
 71     if ( L <= m ) Update( L, c, lson );
 72     else Update( L, c, rson );
 73 
 74     PushUp( rt, l, r );
 75     return;
 76 }
 77 
 78 int Query( int L, int R, int l, int r, int rt )
 79 {
 80     if ( L <= l && r <= R )
 81         return maxLen[rt];
 82 
 83     int m = ( l + r ) >> 1;
 84 
 85     int tempL = 0, tempR = 0;
 86     if ( L <= m ) tempL = Query( L, R, lson );
 87     if ( R > m ) tempR = Query( L, R, rson );
 88 
 89     int ans = max( tempL, tempR );
 90     if ( Rval[rt << 1] < Lval[rt << 1 | 1] )
 91         //这里忘记取最小值,结果样例都不对
 92         ans = max( ans, min( m - L + 1, Rlen[ rt << 1 ] ) + min( R - m, Llen[ rt << 1 | 1 ] ) );
 93 
 94     return ans;
 95 }
 96 
 97 int main()
 98 {
 99     int T;
100     scanf( "%d", &T );
101     while ( T-- )
102     {
103         scanf( "%d%d", &N, &Q );
104         build( 0, N - 1, 1 );
105 
106         while ( Q-- )
107         {
108             char op[4];
109             int a, b;
110             scanf( "%s%d%d", op, &a, &b );
111             if ( op[0] == 'U' )
112                 Update( a, b, 0, N - 1, 1 );
113             else printf("%d\n", Query( a, b, 0, N - 1, 1) );
114         }
115     }
116     return 0;
117 }

 

posted @ 2013-05-09 00:35  冰鸮  阅读(164)  评论(0)    收藏  举报