1. 程式人生 > >POJ 3468 線段樹區間更新

POJ 3468 線段樹區間更新

題意: 輸入 n, m表初始有 n 個數, 接下來 m 行輸入, Q x y 表示詢問區間 [x, y]的和;

         C x y z 表示區間 [x, y] 內所有數加上 z ;

AC_code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<cstdlib>
#define ll long long
#define inf 0x3f3f3f3f//1e9+6e7
#define N 100010
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"**"<<endl
#define lson rt<<1
#define rson rt<<1|1
const double pi=acos(-1.0);
using namespace std;

ll sum[N<<2],add[N<<2];
int a[N];
int n;

void push_up(int rt)    //向上更新
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void push_down(int rt,int m)
{
    if(add[rt]) //若有標記,則將標記向下移動一層
    {
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        sum[rt<<1]+=(m-(m>>1))*add[rt];
        sum[rt<<1|1]+=(m>>1)*add[rt];
        add[rt]=0;  //取消本層標記
    }
}

void build(int l,int r,int rt)  //建樹
{
    add[rt]=0;
    if(l==r)
    {
        sum[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    push_up(rt);    //向上更新
}

void update(int i,int j,ll v,int l,int r,int rt)
{
    if(i <= l && j >= r)
    {
        sum[rt] += (r - l + 1) * v;
        add[rt] += v;
        return;
    }
    push_down(rt, r - l + 1);//向下更新
    int mid = (l + r) >> 1;
    if(i <= mid) update(i, j, v, l,mid,rt<<1);
    if(j > mid) update(i, j, v, mid+1,r,rt<<1|1);
    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 ans=0;
    if(L<=m) ans+=query(L,R,l,m,rt<<1);
    if(R>m) ans+=query(L,R,m+1,r,rt<<1|1);
    return ans;
}

int main()
{
    int q;
    cin>>n>>q;
    for(int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    memset(add,0,sizeof add);
    char s;
    build(1,n,1);
    int i,j;
    ll v;
    ll ans;
    while(q--)
    {
        cin>>s;
        if(s=='C')
        {
            scanf("%d%d%lld",&i,&j,&v);
            update(i,j,v,1,n,1);
        }
        if(s=='Q')
        {
            scanf("%d%d",&i,&j);
            ans=query(i,j,1,n,1);
            printf("%lld\n",ans);
        }
    }
    return 0;
}