SCUT - 321 - Tobby's magic - 线段树

https://scut.online/p/321
第一次做区间线段树。
感觉和单点的一样啊。pushdown的时候要注意一些问题,st的值有可能是跟区间长度有关的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

inline int read() {
    int x=0;
    int f=0;
    char c;
    do {
        c=getchar();
        if(c=='-')
            f=1;
    } while(c<'0'||c>'9');
    do {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    } while(c>='0'&&c<='9');
    return f?-x:x;
}

inline void _write(int x) {
    if(x>9)
        _write(x/10);
    putchar(x%10+'0');
}

inline void write(int x) {
    if(x<0) {
        putchar('-');
        x=-x;
    }
    _write(x);
    putchar('\n');
}

void TestCase(int ti);

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
    //freopen("Yinku.out","w",stdout);
#endif // Yinku
    int T=1;
    for(int ti=1; ti<=T; ti++)
        TestCase(ti);
}

/*---  ---*/


const int MAXM=140000;
int a[MAXM+5];
ll st[(MAXM<<2)+5],lazy[(MAXM<<2)+5];

inline void push_up(int o) {
    st[o]=st[o<<1]+st[o<<1|1];
}

inline void push_down(int o,int l,int r) {
    if(lazy[o]) {
        lazy[o<<1]+=lazy[o];
        lazy[o<<1|1]+=lazy[o];
        int m=(l+r)>>1;
        st[o<<1]+=lazy[o]*(m-l+1);
        st[o<<1|1]+=lazy[o]*(r-m);
        lazy[o]=0;
    }
}

void build(int o,int l,int r) {
    if(l==r)
        st[o]=a[l];
    else {
        int m=(l+r)>>1;
        build(o<<1,l,m);
        build(o<<1|1,m+1,r);
        push_up(o);
    }
    lazy[o]=0;
}

void update(int o,int l,int r,int a,int b,ll v) {
    if(a<=l&&r<=b) {
        lazy[o]+=v;
        st[o]+=v*(r-l+1);
        return;
    } else {
        push_down(o,l,r);
        int m=(l+r)>>1;
        if(a<=m)
            update(o<<1,l,m,a,b,v);
        if(b>=m+1)
            update(o<<1|1,m+1,r,a,b,v);
        push_up(o);
    }
}

ll query(int o,int l,int r,int a,int b) {
    if(a<=l&&r<=b) {
        return st[o];
    } else {
        push_down(o,l,r);
        int m=(l+r)>>1;
        ll ans=0;
        if(a<=m)
            ans=ans+query(o<<1,l,m,a,b);
        if(b>=m+1)
            ans=ans+query(o<<1|1,m+1,r,a,b);
        return ans;
    }
}

inline void TestCase(int ti) {
    int n,m;
    while(~scanf("%d%d",&n,&m)) {
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        build(1,1,n);
        for(int i=1; i<=m; i++) {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(a==1) {
                printf("%lld\n",query(1,1,n,b,c));
            } else {
                int d;
                scanf("%d",&d);
                update(1,1,n,b,c,d);
            }
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/Yinku/p/11039654.html
今日推荐