• POJ 3468 A Simple Problem with Integers 线段树成段更新


    线段树功能  

    update:成段更新  query:区间求和

    #include <iostream>
    #include <string>
    #include <cstdio>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 111111;
    ll sum[MAXN<<2], add[MAXN<<2];
    
    void push_up(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    
    void push_down(int rt, int len)
    {
        if(add[rt] == 0) return;
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        sum[rt<<1] += (len - (len >> 1)) * add[rt];
        sum[rt<<1|1] += (len >> 1) * add[rt];
        add[rt] = 0;
    }
    
    void build(int l, int r, int rt)
    {
        add[rt] = 0;
        if(l == r)
        {
            scanf("%I64d", &sum[rt]);
            return;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        push_up(rt);
    }
    
    void update(int L, int R, int c, int l, int r, int rt)
    {
        if(L <= l && r <= R)
        {
            sum[rt] += c * (r - l + 1);
            add[rt] += c;
            return;
        }
        push_down(rt, r-l+1);
        int m = (l + r) >> 1;
        if(L <= m) update(L, R, c, lson);
        if(R > m) update(L, R, c, rson);
        push_up(rt);
    }
    
    ll query(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R) return sum[rt];
        push_down(rt, r-l+1);
        int m = (l + r) >> 1;
        ll ret = 0;
        if(L <= m) ret += query(L, R, lson);
        if(R > m) ret += query(L, R, rson);
        return ret;
    }
    
    int main()
    {
    //    freopen("in.txt", "r" ,stdin);
        int N, Q;
        while(~scanf("%d%d", &N, &Q))
        {
            build(1, N, 1);
            while(Q--)
            {
                int a, b, c;
                char s[3];
                scanf("%s", s);
                scanf("%d%d", &a, &b);
                if(s[0] == 'Q') printf("%I64d
    ", query(a, b, 1, N, 1));
                else
                {
                    scanf("%d", &c);
                    update(a, b, c, 1, N, 1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    将"089,0760,009"变为 89,760,9
    单向循环链表
    双链表复习
    【C语言】scanf()输入浮点型数据
    【C语言】一元二次方程(求实根和虚根)
    输入一个三位正整数,输出百位数,十位数,个位数
    输入身份证号,输出出生日期
    比较四个数的大小
    比较三个数的大小
    比较两个数的大小
  • 原文地址:https://www.cnblogs.com/pach/p/7418714.html
Copyright © 2020-2023  润新知