线段树模板 区间加减 区间修改

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1000010;
struct node
{
    int l;
    int r;
    int max_val;
    int min_val;
    int sum;
    int addv;
    int setv;
};
node a[maxn<<2], p;
void pushup(int rt)
{
    a[rt].sum = a[rt<<1].sum + a[rt<<1|1].sum;
    a[rt].max_val = max(a[rt<<1].max_val, a[rt<<1|1].max_val);
    a[rt].min_val = min(a[rt<<1].min_val, a[rt<<1|1].min_val);
}
void pushdown(int rt)
{
    int k = a[rt].r - a[rt].l + 1;
    if(a[rt].setv != -1)
    {
        a[rt<<1].setv = a[rt<<1|1].setv = a[rt].setv;
        a[rt<<1].min_val = a[rt<<1|1].min_val = a[rt].setv;
        a[rt<<1].max_val = a[rt<<1|1].max_val = a[rt].setv;
        a[rt<<1].sum = a[rt].setv * (k - (k >> 1));
        a[rt<<1|1].sum = a[rt].setv * (k >> 1);
        a[rt].setv = -1;
        a[rt<<1].addv = 0;
        a[rt<<1|1].addv = 0;
    }
    if(a[rt].addv)
    {
        a[rt<<1].addv += a[rt].addv;
        a[rt<<1].max_val += a[rt].addv;
        a[rt<<1].min_val += a[rt].addv;
        a[rt<<1].sum += a[rt].addv * (k - (k >> 1));

        a[rt<<1|1].addv += a[rt].addv;
        a[rt<<1|1].max_val += a[rt].addv;
        a[rt<<1|1].min_val += a[rt].addv;
        a[rt<<1|1].sum += a[rt].addv * (k >> 1);
        a[rt].addv = 0;
    }

}
void build(int l, int r, int rt)
{
    a[rt].sum = 0;
    a[rt].max_val = 0;
    a[rt].min_val = 0;
    a[rt].addv = 0;
    a[rt].setv = -1;
    a[rt].l = l;
    a[rt].r = r;
    if(l == r)
        return;
    int m = (l + r) >> 1;
    build(l, m, rt<<1);
    build(m+1, r, rt<<1|1);
}

void update(int x, int y, int rt, int v, int key)
{
    if(a[rt].l == x && a[rt].r == y)
    {
        if(key == 1)
        {
            a[rt].addv += v;
            a[rt].sum += (y-x+1)*v;
            a[rt].max_val += v;
            a[rt].min_val += v;
        }
        else
        {
            a[rt].setv = v;
            a[rt].sum = (y-x+1)*v;
            a[rt].max_val = v;
            a[rt].min_val = v;
            a[rt].addv = 0;
        }
        return;
    }
    pushdown(rt);
    int m = (a[rt].l + a[rt].r) >> 1;
    if(y <= m)
        update(x, y, rt<<1, v, key);
    else if(x > m)
        update(x, y, rt<<1|1, v, key);
    else
    {
        update(x, m, rt<<1, v, key);
        update(m+1, y, rt<<1|1, v, key);
    }
    pushup(rt);
}

void query(int x, int y, int rt)
{
    if(a[rt].l == x && a[rt].r == y)
    {
        p.sum += a[rt].sum;
        p.min_val = min(p.min_val, a[rt].min_val);
        p.max_val = max(p.max_val, a[rt].max_val);
        return;
    }
    pushdown(rt);
    int m = (a[rt].l + a[rt].r) >> 1;
    if(y <= m)
        query(x, y, rt<<1);
    else if(x > m)
        query(x, y, rt<<1|1);
    else
    {
        query(x, m, rt<<1);
        query(m+1, y, rt<<1|1);
    }
    pushup(rt);
}
int main()
{
    int t, n, m, ca = 0;
    scanf("%d", &t);
    while(t --) {
        scanf("%d%d", &n, &m);
        build(1, n, 1);
        update(1, n, 1, 1, 2);
        while(m --) {
            int x1, x2, v;
            scanf("%d%d%d", &x1, &x2, &v);
            update(x1, x2, 1, v, 2);
        }
        p.sum = 0;
        query(1, n, 1);
        printf("Case %d: The total value of the hook is %d.\n", ++ ca, p.sum); 
    }
    return 0;
}

posted @ 2014-05-22 22:21  xlc2845  阅读(134)  评论(0)    收藏  举报