简单的线段树应用:
关键词:
线段树、懒操作
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define maxn 100000 + 10
using namespace std;
struct node
{
int l , r ;
long long val , lz;
} nd[maxn<<2] ;
void buildTree( int l , int r , int rt )
{
nd[ rt ].l = l ;
nd[ rt ].r = r ;
nd[ rt ].lz = 0 ;
if( l == r )
{
cin >> nd[rt].val ;
return ;
}
int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
int ls = rt<<1 ;
int rs = ls + 1 ;
buildTree( l , mid , ls ) ;
buildTree( mid + 1 , r , rs ) ;
nd[ rt ].val = (nd[ ls ].val) + (nd[ rs ].val);
}
long long query( int l , int r , int rt )
{
if( nd[ rt ].l == l && nd[ rt ].r == r )
{
return nd[ rt ].val;
}
int ls = rt<<1 ;
int rs = ls + 1 ;
int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
if( nd[ rt ].lz != 0 )
{
nd[ ls ].lz += nd[ rt ].lz ;
nd[ ls ].val += ( mid - nd[ rt ].l + 1 ) * nd[ rt ].lz ;
nd[ rs ].lz += nd[ rt ].lz ;
nd[ rs ].val += ( nd[ rt ].r - mid ) * nd[ rt ].lz ;
nd[ rt ].lz = 0 ;
}
long long ans ;
if( r <= mid ) ans = query( l , r , ls );
else if( l >= mid + 1 ) ans = query( l , r , rs );
else ans = query( l , mid , ls ) + query( mid + 1 , r , rs );
return ans ;
}
void modify( int l , int r , int x , int rt )
{
if( nd[ rt ].l == l && nd[ rt ].r == r )
{
nd[ rt ].lz += x ;
nd[ rt ].val += ( r - l + 1 ) * x ;
return ;
}
int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
int ls = rt<<1 ;
int rs = ls + 1 ;
if( nd[ rt ].lz != 0 )
{
nd[ ls ].lz += nd[ rt ].lz ;
nd[ ls ].val += ( mid - nd[ rt ].l + 1 ) * nd[ rt ].lz ;
nd[ rs ].lz += nd[ rt ].lz ;
nd[ rs ].val += ( nd[ rt ].r - mid ) * nd[ rt ].lz ;
nd[ rt ].lz = 0 ;
}
if( r <= mid) modify( l , r , x , ls );
else if ( l >= mid +1 ) modify( l , r , x , rs );
else
{
modify( l , mid , x , ls );
modify( mid + 1 , r , x , rs );
}
nd[ rt ].val = nd[ ls ].val + nd[ rs ].val ;
}
int main()
{
//freopen("in.txt","r",stdin);
int n , q ;
cin >> n >> q;
buildTree( 1 , n , 1 );
for( int i = 1 ; i <= q ; i ++ )
{
char op[2];
cin >> op ;
if(op[ 0 ] == 'Q')
{
int a , b ;
cin >> a >> b ;
cout<< query( a , b , 1) << endl ;
}
else
{
int a , b , c ;
cin >> a >> b >> c ;
modify( a , b , c , 1);
}
}
return 0;
}