POJ3468 A Simple Problem with Integers

线段树+区间增量累加法lnc 区间更新,区间查询~

#include<cstdio> 
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e6+14;
struct node {
    int l;
    int r;
    ll sum;
    ll lnc;
}segTree[maxn*4];
int num[maxn];
void build (int i,int l,int r) {
    segTree[i].l=l;
    segTree[i].r=r;
    segTree[i].lnc=0;
    if (l==r) {
        segTree[i].sum=num[l];
        return;
    }
    int mid=(l+r)>>1;
    build (i<<1,l,mid);
    build (i<<1|1,mid+1,r);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
} 
void add (int i,int a,int b,ll c) {
    if (segTree[i].l==a&&segTree[i].r==b) {
        segTree[i].lnc+=c;
        return;
    }
    segTree[i].sum+=c*(b-a+1);
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if (b<=mid) add(i<<1,a,b,c);
    else if (a>mid) add(i<<1|1,a,b,c);
    else {
        add(i<<1,a,mid,c);
        add(i<<1|1,mid+1,b,c);
    } 
}
ll query (int i,int a,int b) {
    if (segTree[i].l==a&&segTree[i].r==b) {
        return segTree[i].sum+(b-a+1)*segTree[i].lnc;
    }
    segTree[i].sum+=(segTree[i].r-segTree[i].l+1)*segTree[i].lnc;
    int mid=(segTree[i].l+segTree[i].r)>>1;
    add(i<<1,segTree[i].l,mid,segTree[i].lnc);
    add(i<<1|1,mid+1,segTree[i].r,segTree[i].lnc);
    segTree[i].lnc=0;
    if (b<=mid) return query(i<<1,a,b);
    else if (a>mid) return query(i<<1|1,a,b);
    else return query(i<<1,a,mid)+query(i<<1|1,mid+1,b);
}
int main () {
    int n;
    int q;
    int a,b,c;
    char ch;
    while (~scanf("%d %d",&n,&q)) {
        for (int i=1;i<=n;i++) scanf ("%d",&num[i]);
        build (1,1,n);
        for (int i=1;i<=q;i++) {
            cin>>ch;
            if (ch=='C') scanf ("%d %d %d",&a,&b,&c),add(1,a,b,c);
            else {
                scanf ("%d %d",&a,&b);
                printf ("%lld\n",query(1,a,b));
            }
        } 
    }
    return 0;
}

 

posted @ 2020-02-14 11:27  zlc0405  阅读(101)  评论(0编辑  收藏  举报