暑假前专题题解---数据结构---B

线段树的基本区间操作

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int maxn = 1e6 + 10;

LL sum[maxn<<2],p[maxn<<2];

LL sum1;

void up(int id){

    sum[id] = sum[id<<1] + sum[id<<1|1];

}

void down(int l,int r,int id){

    int mid = (l + r) >> 1;

    if (p[id]){

        p[id<<1] += p[id];

        p[id<<1|1] += p[id];

        sum[id<<1] += p[id]*(mid-l+1);

        sum[id<<1|1] += p[id]*(r-mid);

        p[id] = 0;

    }

}

void rev(int l,int r,int id,int L,int R,int c){

    if (L <= l && r <= R){

        p[id] += c;

        sum[id] += (r - l + 1) * c;

        return ;

    }

    int mid = (l + r) >> 1;

    down(l, r, id);

    if (L <= mid) rev(l, mid, id<<1, L, R, c);

    if (R > mid) rev(mid+1, r, id<<1|1, L, R, c);

    up(id);

}

void query(int l,int r,int id,int L,int R){

    if (L <= l && r <= R){

        sum1 += sum[id];

        return;

    }

    int mid = (l + r) >> 1;

    down(l,r,id);

    if (L <= mid) query(l, mid, id<<1, L, R);

    if (R > mid) query(mid+1, r, id<<1|1, L, R);

}

int main(){

    int n,m,o,l,r,v;

    scanf("%d%d",&n,&m);

    for (int i=0; i<m; i++) {

        scanf("%d %d %d %d",&o,&l,&r,&v);

        if (o == 0) rev(1, n, 1, l, r, v);

        else{

            query(1, n, 1, l, r);

            printf("%lld\n",sum1);

            sum1 = 0;

        }

    }

    return 0;

}

猜你喜欢

转载自blog.csdn.net/CCCCTong/article/details/81381912