求区间内最长连续上升子序列
线段树典型区间合并
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 }