首页 > 代码库 > POJ 3468 A Simple Problem with Integers 线段树 区间更新 区间查询

POJ 3468 A Simple Problem with Integers 线段树 区间更新 区间查询

  题目链接: http://poj.org/problem?id=3468

  题目描述: 一组数列, 可进行一段区间加上某一个数, 和区间查询 

  解题思路: 线段树, 之前的那道题是求总区间直接输出sum[1] 就可以了, 这次有了区间查询, 同理, 查询的时候Pushdown 

  代码: 

技术分享
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
typedef long long LL;
using namespace std;
int cases;
const int maxn = 1e5+100;
int n;
int q;
LL sum[maxn<<2];
LL add[maxn<<2];
char op[4];

void pushUp( int rt ) {
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void pushDown( int rt, int x ) {
    if( add[rt] ) {
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        sum[rt<<1] += (x - (x>>1)) * add[rt];
        sum[rt<<1|1] += (x>>1) * add[rt];
        add[rt] = 0;
    }
}

void upDate( int L, int R, int x, int l, int r, int rt ) {
    if( L <= l && r <= R ) {
        add[rt] += x;
        sum[rt] += (LL)(r - l + 1) * x;
        return;
    }
    pushDown( rt, r - l + 1 );
    int m = (l + r) >> 1;
    if( L <= m ) upDate(L, R, x, lson);
    if( R > m ) upDate(L, R, x, rson);
    pushUp(rt);
}

void build( int l, int r, int rt ) {
    add[rt] = 0;
    if( l == r ) {
        scanf( "%lld", &sum[rt] );
        return;
    }
    int m = (l + r) >> 1;
    build( lson );
    build( rson );
    pushUp( rt );
    return;
}

LL Query( int L, int R, int l, int r, int rt ) {
    if( L <= l && r <= R ) {
        return sum[rt];
    }
    pushDown(rt, r - l + 1);
    LL ret = 0;
    int m = (l + r) >> 1;
    if( L <= m ) ret += Query( L, R, lson );
    if( R > m ) ret += Query( L, R, rson );
    return ret;
}

int main() {
    while( scanf( "%d%d", &n, &q ) == 2 ) {
        build( 1, n, 1 );
        while( q-- ) {
            scanf( "%s", op );
            if( op[0] == C ) {
                int a, b, c;
                scanf( "%d%d%d", &a, &b, &c );
                upDate( a, b, c, 1, n, 1 );
            }
            else {
                int a, b;
                scanf( "%d%d", &a, &b );
                printf( "%lld\n", Query( a, b, 1, n , 1) );
            }
        }
    }
    return 0;
}
View Code

  思考: 本身题没啥可说的, 和上道题很类似, 但是我在pushdown函数中sum[rt] ..... 应该是加等于的, 我写成了 等于所以一直卡在那里半个小时....发现的时候就觉得自己特别蠢。 以后应该仔细一点儿

POJ 3468 A Simple Problem with Integers 线段树 区间更新 区间查询