今天终于写了一道正常的题
思路是这样的:
1.普通线段树add,set不变,并改为下放标记版本
2.past_addv 记录一个区间内可能的addv值的最大值
3.past_setv 记录一个区间被set的最大值
4.maxv与past_maxv为值
代码风格导致比较长
1 #include<cstdio> 2 #include<climits> 3 #include<cctype> 4 #include<algorithm> 5 6 using std :: max ; 7 8 const int MAXN = 1024 * 128 + 20 ; 9 const int NONE = INT_MIN ; 10 int N ; 11 12 void max_equal ( int & a , const int b ) { 13 if ( b > a ) a = b ; 14 } 15 16 int get_int () { 17 int v ; 18 scanf ( "%d" , & v ) ; 19 return v ; 20 } 21 22 int addv [ MAXN * 2 ] ; 23 int setv [ MAXN * 2 ] ; 24 int maxv [ MAXN * 2 ] ; 25 26 int past_addv [ MAXN * 2 ] ; 27 int past_setv [ MAXN * 2 ] ; 28 int past_maxv [ MAXN * 2 ] ; 29 30 void M_add ( const int o , const int v ) { 31 if ( setv [ o ] != NONE ) { 32 setv [ o ] += v ; max_equal ( past_setv [ o ] , setv [ o ] ) ; 33 } else { 34 addv [ o ] += v ; max_equal ( past_addv [ o ] , addv [ o ] ) ; 35 } 36 } 37 38 void M_set ( const int o , const int v ) { 39 setv [ o ] = v ; max_equal ( past_setv [ o ] , setv [ o ] ) ; 40 } 41 42 void P_add ( const int o , const int v ) { 43 if ( setv [ o ] != NONE ) { 44 max_equal ( past_setv [ o ] , setv [ o ] + v ) ; 45 } else { 46 max_equal ( past_addv [ o ] , addv [ o ] + v ) ; 47 } 48 } 49 50 void P_set ( const int o , const int v ) { 51 max_equal ( past_setv [ o ] , v ) ; 52 } 53 54 void push_down ( const int o ) { 55 const int o1 = o << 1 ; 56 const int o2 = o << 1 | 1 ; 57 if ( past_addv [ o ] ) { 58 P_add ( o1 , past_addv [ o ] ) ; 59 P_add ( o2 , past_addv [ o ] ) ; 60 past_addv [ o ] = 0 ; 61 } 62 if ( addv [ o ] ) { 63 M_add ( o1 , addv [ o ] ) ; 64 M_add ( o2 , addv [ o ] ) ; 65 addv [ o ] = 0 ; 66 } 67 if ( past_setv [ o ] != NONE ) { 68 P_set ( o1 , past_setv [ o ] ) ; 69 P_set ( o2 , past_setv [ o ] ) ; 70 past_setv [ o ] = NONE ; 71 } 72 if ( setv [ o ] != NONE ) { 73 M_set ( o1 , setv [ o ] ) ; 74 M_set ( o2 , setv [ o ] ) ; 75 setv [ o ] = NONE ; 76 } 77 } 78 79 void maintain ( const int o , const int L , const int R ) { 80 const int o1 = o << 1 ; 81 const int o2 = o << 1 | 1 ; 82 if ( R - L == 1 ) { 83 maxv [ o ] = setv [ o ] ; 84 max_equal ( past_maxv [ o ] , past_setv [ o ] ) ; 85 } else { 86 maxv [ o ] = 87 ( setv [ o ] == NONE ) ? max ( maxv [ o1 ] , maxv [ o2 ] ) + addv [ o ] : setv [ o ] ; 88 max_equal ( past_maxv [ o ] , past_setv [ o ] ) ; 89 max_equal ( past_maxv [ o ] , max ( maxv [ o1 ] , maxv [ o2 ] ) + past_addv [ o ] ) ; 90 max_equal ( past_maxv [ o ] , max ( past_maxv [ o1 ] , past_maxv [ o2 ] ) ) ; 91 } 92 } 93 94 static struct { 95 void W ( const int o , const int L , const int R ) { 96 setv [ o ] = past_setv [ o ] = maxv [ o ] = past_maxv [ o ] = NONE ; 97 addv [ o ] = past_addv [ o ] = 0 ; 98 if ( R - L == 1 ) { 99 M_set ( o , get_int () ) ; 100 } else { 101 const int M = ( L + R ) >> 1 ; 102 W ( o << 1 , L , M ) ; 103 W ( o << 1 | 1 , M , R ) ; 104 } 105 maintain ( o , L , R ) ; 106 } 107 void operator ( ) ( ) { 108 scanf ( "%d" , & N ) ; 109 W ( 1 , 1 , N + 1 ) ; 110 } 111 } Build ; 112 113 114 static struct { 115 int l , r , v ; 116 void W ( const int o , const int L , const int R ) { 117 if ( l <= L && R <= r ) { 118 M_set ( o , v ) ; 119 } else { 120 const int M = ( L + R ) >> 1 ; 121 push_down ( o ) ; 122 if ( l < M ) W ( o << 1 , L , M ) ; else maintain ( o << 1 , L , M ) ; 123 if ( M < r ) W ( o << 1 | 1 , M , R ) ; else maintain ( o << 1 | 1 , M , R ) ; 124 } 125 maintain ( o , L , R ) ; 126 } 127 void operator () ( const int L , const int R , const int V ) { 128 l = L ; r = R + 1 ; v = V ; 129 W ( 1 , 1 , N + 1 ) ; 130 } 131 } Set ; 132 133 static struct { 134 int l , r , v ; 135 void W ( const int o , const int L , const int R ) { 136 if ( l <= L && R <= r ) { 137 M_add ( o , v ) ; 138 } else { 139 const int M = ( L + R ) >> 1 ; 140 push_down ( o ) ; 141 if ( l < M ) W ( o << 1 , L , M ) ; else maintain ( o << 1 , L , M ) ; 142 if ( M < r ) W ( o << 1 | 1 , M , R ) ; else maintain ( o << 1 | 1 , M , R ) ; 143 } 144 maintain ( o , L , R ) ; 145 } 146 void operator () ( const int L , const int R , const int V ) { 147 l = L ; r = R + 1 ; v = V ; 148 W ( 1 , 1 , N + 1 ) ; 149 } 150 } Add ; 151 152 static struct { 153 int l , r , ans ; 154 void W ( const int o , const int L , const int R ) { 155 if ( l <= L && R <= r ) { 156 max_equal ( ans , maxv [ o ] ) ; 157 } else { 158 const int M = ( L + R ) >> 1 ; 159 push_down ( o ) ; 160 maintain ( o << 1 , L , M ) ; 161 maintain ( o << 1 | 1 , M , R ) ; 162 if ( l < M ) W ( o << 1 , L , M ) ; 163 if ( M < r ) W ( o << 1 | 1 , M , R ) ; 164 } 165 } 166 int operator () ( const int L , const int R ) { 167 l = L ; r = R + 1 ; ans = NONE ; 168 W ( 1 , 1 , N + 1 ) ; 169 return ans ; 170 } 171 } Qmax ; 172 173 static struct { 174 int l , r , ans ; 175 void W ( const int o , const int L , const int R ) { 176 if ( l <= L && R <= r ) { 177 max_equal ( ans , past_maxv [ o ] ) ; 178 } else { 179 const int M = ( L + R ) >> 1 ; 180 push_down ( o ) ; 181 maintain ( o << 1 , L , M ) ; 182 maintain ( o << 1 | 1 , M , R ) ; 183 if ( l < M ) W ( o << 1 , L , M ) ; 184 if ( M < r ) W ( o << 1 | 1 , M , R ) ; 185 } 186 } 187 int operator () ( const int L , const int R ) { 188 l = L ; r = R + 1 ; ans = NONE ; 189 W ( 1 , 1 , N + 1 ) ; 190 return ans ; 191 } 192 } Q_past_max ; 193 194 int T , E , opt , X , Y , Z ; 195 int main () { 196 Build ( ) ; 197 scanf ( "%d" , & E ) ; 198 while ( E -- ) { 199 while ( isspace ( opt = getchar () ) ) ; 200 switch ( opt ) { 201 case 'Q' : 202 scanf ( "%d%d" , & X , & Y ) ; 203 printf ( "%d\n" , Qmax ( X , Y ) ) ; 204 break ; 205 case 'A' : 206 scanf ( "%d%d" , & X , & Y ) ; 207 printf ( "%d\n" , Q_past_max ( X , Y ) ) ; 208 break ; 209 case 'P' : 210 scanf ( "%d%d%d" , & X , & Y , & Z ) ; 211 Add ( X , Y , Z ) ; 212 break ; 213 case 'C' : 214 scanf ( "%d%d%d" , & X , & Y , & Z ) ; 215 Set ( X , Y , Z ) ; 216 break ; 217 } 218 } 219 return 0 ; 220 }