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 }

 

你可能感兴趣的:(HDU)