从这题似乎感悟到了点线段树对区间操作的lazy思想,即只需要找到合适区间对其更新并标记,子区间暂不更新。通过画图模拟更加直观。 #include <iostream> using namespace std; const int Max = 100000; // 对象 struct TreeNode { int l, r; long long c; // 增量 long long sum; // 区间和 }tree[Max*4]; //-----------------线段树操作-------------------// void Build( const int l, const int r, const int id ) { tree[id].l = l; tree[id].r = r; tree[id].c = 0; tree[id].sum = 0; if( r - l == 1 ) return; int mid = ( l + r ) >> 1; Build( l, mid, id * 2 ); Build( mid, r, id * 2 + 1 ); } void Update( const int l, const int r, const int v, const int id ) { if( tree[id].l == l && tree[id].r == r ) { tree[id].sum += ( r - l ) * v; // 区间每个元素加v tree[id].c += v; // lazy思想,记录该区间的增量,供求子区间和时使用 return; } if( tree[id].c != 0 ) { tree[ id*2 ].sum += ( tree[ id*2 ].r - tree[ id*2 ].l ) * tree[id].c; tree[ id*2+1 ].sum += ( tree[ id*2+1 ].r - tree[ id*2+1 ].l ) * tree[id].c; tree[ id*2 ].c += tree[id].c; tree[ id*2+1 ].c += tree[id].c; tree[id].c = 0; } int mid = ( tree[id].l + tree[id].r ) >> 1; if( r <= mid ) Update( l, r, v, id * 2 ); else if( l >= mid ) Update( l, r, v, id * 2 + 1 ); else { Update( l, mid, v, id * 2 ); Update( mid, r, v, id * 2 + 1 ); } // 合并 tree[id].sum = tree[ id*2 ].sum + tree[ id*2+1 ].sum; } long long Query( const int l, const int r, const int id ) { if( tree[id].l == l && tree[id].r == r ) { return tree[id].sum; } if( tree[id].c != 0 ) { tree[ id*2 ].sum += ( tree[ id*2 ].r - tree[ id*2 ].l ) * tree[id].c; tree[ id*2+1 ].sum += ( tree[ id*2+1 ].r - tree[ id*2+1 ].l ) * tree[id].c; tree[ id*2 ].c += tree[id].c; tree[ id*2+1 ].c += tree[id].c; tree[id].c = 0; } int mid = ( tree[id].l + tree[id].r ) >> 1; if( r <= mid ) return Query( l, r, id * 2 ); else if( l >= mid ) return Query( l, r, id * 2 + 1 ); else return Query( l, mid, id * 2 ) + Query( mid, r, id * 2 + 1 ); } //-----------------------------------------------------// int main() { int N, M, a, b, v; while( scanf( "%d%d", & N, & M ) == 2 ) { Build( 1, N + 1, 1 ); for( int i = 1; i <= N; ++ i ) { scanf( "%d", & v ); Update( i, i + 1, v, 1 ); } char ch; while( M-- ) { getchar(); scanf( "%c%d%d", & ch, & a, & b ); if( ch == 'Q' ) { long long sum = Query( a, b + 1, 1 ); printf( "%lld/n", sum ); } else { scanf( "%d", & v ); Update( a, b + 1, v, 1 ); } } } system( "pause" ); return 0; }