poj 3468 -- A Simple Problem with Integers ( 线段树 , 段更新 , 段求和 )

# include <cstdio>
# include <iostream>
# include <set>
# include <map>
# include <vector>
# include <list>
# include <queue>
# include <stack>
# include <cstring>
# include <string>
# include <cstdlib>
# include <cmath>
# include <algorithm>

using namespace std ;

const int maxn = 110000 ;
long long summ ;

struct Tree
{
    long long sum ;
    long long flag ;
} tree [ maxn * 4 ] ;

void pushup ( int pos )
{
    tree [ pos ] . sum = tree [ pos * 2 ] . sum + tree [ pos * 2 + 1 ] . sum ;
}

void pushdown ( int l , int r , int pos )
{
    int m = ( l + r ) / 2 ;
    long long val = tree [ pos ] . flag ;
    tree [ pos ] . flag = 0 ;
    tree [ pos * 2 ] . sum += ( m - l + 1 ) * val ;
    tree [ pos * 2 + 1 ] . sum += ( r - m ) * val ;
    tree [ pos * 2 ] . flag += val ;
    tree [ pos * 2 + 1 ] . flag += val ;
}

void build ( int l , int r , int pos )
{
    if ( l == r )
    {
        scanf ( "%lld" , & tree [ pos ] . sum ) ;
        return ;
    }
    int m = ( l + r ) / 2 ;
    build ( l , m , pos * 2 ) ;
    build ( m + 1 , r , pos * 2 + 1 ) ;
    pushup ( pos ) ;
}

void update ( int l , int r , int pos , int L , int R , long long val )
{
    if ( l >= L && r <= R )
    {
        tree [ pos ] . flag += val ;
        tree [ pos ] . sum += val * ( r - l + 1 ) ;
        return ;
    }
    if ( tree [ pos ] . flag )
        pushdown ( l , r , pos ) ;
    int m = ( l + r ) / 2 ;
    if ( m >= L )
        update ( l , m , pos * 2 , L , R , val ) ;
    if ( m + 1 <= R )
        update ( m + 1 , r , pos * 2 + 1 , L , R , val ) ;
    pushup ( pos ) ;
}

void quer ( int l , int r , int pos , int L , int R )
{
    if ( l >= L && r <= R )
    {
        summ += tree [ pos ] . sum ;
        return ;
    }
    if ( tree [ pos ] . flag )
        pushdown ( l , r , pos ) ;
    int m = ( l + r ) / 2 ;
    if ( m >= L )
        quer ( l , m , pos * 2 , L , R ) ;
    if ( m + 1 <= R )
        quer ( m + 1 , r , pos * 2 + 1 , L , R ) ;
}

int main ( )
{
    int n , q ;
    scanf ( "%d%d" , & n , & q ) ;
    build ( 1 , n , 1 ) ;
    getchar ( ) ;
    while ( q -- )
    {
        char c ;
        c = getchar ( ) ;
        if ( c == 'Q' )
        {
            int a , b ;
            scanf ( "%d%d" , & a , & b ) ;
            summ = 0 ;
            quer ( 1 , n , 1 , a , b ) ;
            printf ( "%lld\n" , summ ) ;
        }
        else
        {
            int a , b ;
            long long c ;
            scanf ( "%d%d%lld" , & a , & b , & c ) ;
            update ( 1 , n , 1 , a , b , c ) ;
        }
        getchar ( ) ;
    }
}

你可能感兴趣的:(poj 3468 -- A Simple Problem with Integers ( 线段树 , 段更新 , 段求和 ))