POJ-3468-线段树-A Simple Problem with Integers

题意
求区间和
C abc表示给区间[a,b]里的数都加上c
思路
线段树+区间更新

区间更新就是在update时不一下全部更新 而是在区间上留下标记
当查询区间时,再将标记向下传递 更新
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
const int maxn = 100100;
long long sum[maxn << 2];
long long  addmark[maxn << 2];
void pushup(int root)
{
    sum[root] = sum[root << 1] + sum[root << 1 | 1];

}
void pushdown(int root,int m)
{
    if (addmark[root])
    {
        addmark[root << 1] += addmark[root];
        addmark[root << 1 | 1] += addmark[root];
        sum[root << 1] += addmark[root] * (m - (m >> 1));
        sum[root << 1 | 1] += addmark[root] * (m >> 1);
        addmark[root] = 0;
    }

}
void build(int l, int r, int root)
{
    addmark[root] = 0;
    if (r == l)
    {
        scanf("%lld", &sum[root]);
        return;
    }
    int m = (l + r) >> 1;
    build(l, m, root << 1);
    build(m + 1, r, root << 1 | 1);
    pushup(root);
}
void update(int L, int R, int l, int r, int root,int c)
{
    if (L <= l&&r <= R)
    {
        addmark[root] += c;
        sum[root] += (long long)c*(r - l + 1);
        return;


    }
    pushdown(root, r - l + 1);
    int m = (l + r) >> 1;
    if (L <= m) update(L, R, l, m, root << 1,c);
    if (R > m) update(L, R, m + 1, r, root << 1 | 1, c);
    pushup(root);


}
long long  query(int L, int R, int l, int r, int root)
{
    if (L <= l&&r <= R)
    {
        return sum[root];
    }
    pushdown(root, r - l + 1);
    int m = (l + r) >> 1;
    long long ans = 0;
    if (L <= m) ans += query(L, R, l, m, root << 1);
    if (m < R) ans += query(L, R, m + 1, r, root << 1 | 1);
    return ans;

}

int main(void)
{
    int n,q;
    cin >> n >> q;
    build(1, n, 1);
    while (q--)
    {
        char s[5];
        int a, b, c;
        scanf("%s", s);
        if (s[0] == 'Q')
        {
            scanf("%d%d", &a, &b);
            cout << query(a, b, 1, n, 1) << endl;
        }
        else
        {
            scanf("%d%d%d", &a, &b, &c);
            update(a, b, 1, n, 1, c);

        }
    }

    return 0;
}

你可能感兴趣的:(ACM)