http://blog.csdn.net/acm_cxlove/article/details/7548087
感觉最巧的是定义了min_dis……将区间内有无英雄升级分开处理
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define lc rt << 1 #define rc rt << 1 | 1 using namespace std; const int MAXN = 12222; const int INF = 1 << 30; struct node { int exp, level; int min_dis; int flag; }; int N, K, Q; node Tr[ MAXN << 2 ]; int sum[20]; void build( int l, int r, int rt ) { Tr[rt].exp = Tr[rt].flag = 0; Tr[rt].level = 1; Tr[rt].min_dis = sum[1]; if ( l == r ) return ; int m = ( l + r ) >> 1; build( lson ); build( rson ); return; } void PushDown( int rt ) { if ( Tr[rt].flag ) { Tr[lc].exp += Tr[rt].flag * Tr[lc].level; Tr[lc].min_dis -= Tr[rt].flag; Tr[lc].flag += Tr[rt].flag; Tr[rc].exp += Tr[rt].flag * Tr[rc].level; Tr[rc].min_dis -= Tr[rt].flag; Tr[rc].flag += Tr[rt].flag; Tr[rt].flag = 0; } return; } void PushUp( int rt ) { Tr[rt].level = max( Tr[lc].level, Tr[rc].level ); Tr[rt].exp = max( Tr[lc].exp, Tr[rc].exp ); Tr[rt].min_dis = min( Tr[lc].min_dis, Tr[rc].min_dis ); return; } void Update( int L, int R, int v, int l, int r, int rt ) { if ( l == r ) { Tr[rt].exp += Tr[rt].level * v; while ( Tr[rt].exp >= sum[ Tr[rt].level ] ) ++Tr[rt].level; Tr[rt].min_dis = ( sum[ Tr[rt].level ] - Tr[rt].exp ) / Tr[rt].level; if( ( sum[ Tr[rt].level ] - Tr[rt].exp ) % Tr[rt].level ) ++Tr[rt].min_dis; return; } int m = ( l + r ) >> 1; if ( L == l && r == R ) { if ( v >= Tr[rt].min_dis ) { PushDown(rt); if ( R <= m ) Update( L, R, v, lson ); else if ( L > m ) Update( L, R, v, rson ); else { Update( L, m, v, lson ); Update( m + 1, R, v, rson ); } PushUp(rt); } else { Tr[rt].exp += Tr[rt].level * v; Tr[rt].min_dis -= v; Tr[rt].flag += v; } return; } PushDown(rt); if ( R <= m ) Update( L, R, v, lson ); else if ( L > m ) Update( L, R, v, rson ); else { Update( L, m, v, lson ); Update( m + 1, R, v, rson ); } PushUp(rt); return; } int Query( int L, int R, int l, int r, int rt ) { if ( L <= l && r <= R ) return Tr[rt].exp; PushDown(rt); int m = ( l + r ) >> 1; int res = 0; if ( L <= m ) res = max( res, Query( L, R, lson ) ); if ( R > m ) res = max( res, Query( L, R, rson ) ); //PushUp(rt); return res; } int main() { int T; int cas = 0; scanf( "%d", &T ); while ( T-- ) { scanf( "%d%d%d", &N, &K, &Q ); for ( int i = 1; i < K; ++i ) scanf( "%d", &sum[i] ); sum[K] = INF; build( 1, N, 1 ); printf( "Case %d:\n", ++cas ); while ( Q-- ) { char op[4]; int a, b, c; scanf( "%s", op ); if ( op[0] == 'W' ) { scanf( "%d%d%d", &a, &b, &c ); Update( a, b, c, 1, N, 1 ); } else { scanf( "%d%d", &a, &b ); printf("%d\n", Query( a, b, 1, N, 1 ) ); } } puts(""); } return 0; }