POJ 3468 Continue segment tree

This time I wrote it after the last line segment tree. Last time I only wrote a single point modification of the line segment tree, and the interval is the maximum value.

However, I continued to learn the interval modification of line segment trees and the problem of interval summation.

And then, this time it must be about;

The interval modification of the line segment tree, the interval is the maximum value:

After learning it, I feel that it is similar to the previous ones. It is an idea, but for the modification of an interval, that is, each value in the interval needs to be added with the same value, and the time is the total sum and sum of the interval modification. , which is the number of elements in the interval multiplied by the value of the add array. The add array stores the added value of each interval element in a certain interval. (The general idea is to maintain each interval through recursion and dichotomy after modification).

Topic link: Click to open the link

This is also a pure template question, as long as you know the template, you can AC, haha

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;

#define lson ri<<1,l,m //This is a little trick I learned online
#define rson ri<<1|1,m+1,r

ll sum[maxn<<2], add[maxn<<2];

struct Node {
    int left ,right;
    int mid (){
        return (left + right)>>1;
    }
}tree[maxn<<2];

void PushUp (int ri){
    sum[ri] = sum[ri<<1] + sum[ri<<1|1];  // sum[ri<<1|1] 相当于sum[(ri<<1)+1]
}

void PushDown (int ri, int m){
    if (add[ri]){
        add[ri<<1] += add[ri];
        add[ri<<1|1] += add[ri];
        sum[ri<<1] += add[ri] * (m-(m>>1));
        sum[ri<<1|1] += add[ri] *(m>>1);
        add[ri] = 0;
    }
}

void build (int ri, int l, int r){
    //cout << "text\n";
    tree[ri].left = l;
    tree[ri].right = r;
    add[ri] = 0;
    if (l == r){
        //cin >> sum[ri];
        scanf("%I64d",&sum[ri]);
        return ;
    }
    int m = tree[ri].mid();
    build (lson);
    build (rson);
    PushUp (ri);
}

void Update (int key,int l, int r, int ri){
    if (tree[ri].left == l && tree[ri].right == r){
        add[ri] += key;
        sum[ri] +=(ll) key * (r - l + 1);
        return ;
    }
    if (tree[ri].left == tree[ri].right)  return ;
    PushDown(ri,tree[ri].right - tree[ri].left + 1);
    int m = tree[ri].mid();
    if (r <= m){
        Update (key,l,r,ri<<1);
    }
    else if (l > m){
        Update (key, l, r, ri <<1|1);
    }
    else{
        Update (key,l, m , ri<<1);
        Update (key, m+1, r, ri<<1|1);
    }
    PushUp (ri);
}

ll search (int l, int r, int ri){
    if (tree[ri].left == l && tree[ri].right == r){
        return sum[ri];
    }
    PushDown (ri, tree[ri].right - tree[ri].left + 1);
    int m = tree[ri].mid();
    ll res = 0;
    if (r <= m){
        res += search (l, r, ri<<1);
    }
    else if (l > m){
        res += search (l, r, ri<<1|1);
    }
    else{
        res += search (l,m,ri<<1);
        res += search (m+1, r, ri<<1|1);
    }
    return res;
}

int main (){
    //ios::sync_with_stdio(false);
    int n, m;
    while (~scanf("%d%d",&n,&m)){
        build (1, 1, n);
        //cout << "text\n";
        while (m--){
            //cout << "text\n";
            char ch[2];
            int a,b,c;
            //cin >> ch;
            scanf("%s",ch);
            if (ch[0] == 'Q'){
//                cin >>a >> b;
//                cout << search (a,b,1) <<endl;
                scanf("%d%d",&a,&b);
                printf("%I64d\n",search(a,b,1));
            }
            else{
                //cin >> a >> b >> c;
                scanf("%d%d%d",&a,&b,&c);
                Update (c, a, b, 1);
            }
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325885180&siteId=291194637