poj 3468 經典線段樹

 只要加一個lazy就行了,注意的是update和query裏的return條件。只要當前區間包含於查詢區間就可以直接返回了。

當時沒注意,只在query裏設置了,update裏沒用lazy(汗

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include <bitset>
#define  LL long long
#define  ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
#define maxn 100005
using namespace std;
LL sum[maxn << 2];
LL lazy[maxn << 2];
LL a[maxn];
LL n;
void pushUp(LL rt)
{
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void pushDown(LL ln,LL rn,LL rt)
{
    if(lazy[rt]){
      lazy[rt << 1] += lazy[rt];
      lazy[rt << 1|1] += lazy[rt];
      sum[rt << 1] += lazy[rt] * ln;
      sum[rt << 1|1] += lazy[rt] * rn;
      lazy[rt] = 0;
    }
}
void build_tree(LL left,LL right,LL rt)
{
    if(left == right){
        sum[rt] = a[left];
        return;
    }
    LL mid = (left + right) >> 1;
    build_tree(left , mid , rt << 1);
    build_tree(mid + 1 , right , rt << 1 | 1);
    pushUp(rt);
}
void update(LL L,LL R,LL v,LL left,LL right,LL rt)
{
    if(L <= left && right <= R){
        sum[rt] += v * (right - left + 1);
        lazy[rt] += v;
        return;
    }
    LL mid = (left + right) >> 1;
    pushDown(mid - left + 1,right - mid,rt);
    if(L <= mid) update(L,R,v,left,mid,rt << 1);
    if(R > mid) update(L,R,v,mid + 1,right,rt << 1 | 1);
    pushUp(rt);
}
LL query(LL L,LL R,LL left,LL right,LL rt)
{
    if(L <= left && right <= R){
        return sum[rt];
    }

    LL mid = (left + right) >> 1;
    pushDown(mid - left + 1, right - mid, rt);
    LL ans = 0;
    if(L <= mid) ans += query(L,R,left,mid,rt << 1);
    if(R > mid)  ans += query(L,R,mid + 1,right,rt << 1 | 1);
    return ans;
}
int main()
{
    LL m;
    while(~scanf("%lld%lld",&n,&m)){
      mem(sum,0);
      mem(lazy,0);
      for(LL i = 1; i <= n; i++) scanf("%lld",&a[i]);
      build_tree(1,n,1);
      char c[2];
      LL L,R;
      while(m--){
        //getchar();
        scanf("%s",c);
        if(c[0] == 'Q'){
            scanf("%lld%lld",&L,&R);
            printf("%lld\n",query(L,R,1,n,1));
            /*for(int i = 1; i <= n*4; i++) printf("%d--%d ",i,a[i]);
           printf("\n");
           for(int i = 0; i <= n*4; i++) printf("%d--%d ",i,sum[i]);
           printf("\n");*/
        }
        if(c[0] == 'C'){
           LL v;
           scanf("%lld%lld%lld",&L,&R,&v);
           update(L,R,v,1,n,1);

        }
      }
    }


    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章