POJ - 3468线段树--区间求和模板


这是线段树区间求和的模板,保留以后直接copy使用。







#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define siz 100005
#define LL __int64
using namespace std;
struct node{
    LL data,addMark;
};
node arr[siz*4];
LL p[siz];
int n,m;
void build(int root,int start,int ends){
     if(start==ends){
        arr[root].data=p[ends];
        arr[root].addMark=0;
        return ;
     }
     int mid=(start+ends)>>1;
     build(root<<1,start,mid);
     build((root<<1)+1,mid+1,ends);
     arr[root].data=arr[root<<1].data+arr[(root<<1)+1].data;
     arr[root].addMark=0;
}
void pushDown(int root,int m){
    if(arr[root].addMark!=0){
        arr[root*2].addMark+=arr[root].addMark;
        arr[root*2+1].addMark+=arr[root].addMark;
        arr[root*2].data+=(m-(m>>1))*arr[root].addMark;
        arr[root*2+1].data+=(m>>1)*arr[root].addMark;
        arr[root].addMark=0;
    }
}
LL query(int root,int s,int e,int start,int ends){
    if(s==start&&e==ends) return arr[root].data;
    pushDown(root,e-s+1);
    int mid=(s+e)/2;
    //printf("%d %d %d\n",root,start,ends);
    if(ends<=mid) return query(root<<1,s,mid,start,ends);
    else if(start>mid) return query((root<<1)+1,mid+1,e,start,ends);
    else
    return query(root*2,s,mid,start,mid)+query(root*2+1,mid+1,e,mid+1,ends);
}
void updata(int root,int s,int e,int st,int ends,int va){
    if(st>e||s>ends) return ;
    if(st==s&&e==ends){
        arr[root].addMark+=va;
        arr[root].data+=(ends-st+1)*va;
        return ;
    }
    pushDown(root,e-s+1);
    int mid=(s+e)>>1;
    if(ends<=mid) updata(root<<1,s,mid,st,ends,va);
    else if(st>mid) updata((root<<1)+1,mid+1,e,st,ends,va);
    else{
        updata(root<<1,s,mid,st,mid,va);
        updata((root<<1)+1,mid+1,e,mid+1,ends,va);
    }
    arr[root].data=arr[root<<1].data+arr[(root<<1)+1].data;
}
void solve(){
    //int m;
    //scanf("%d",&m);

   for(int i=1;i<=m;i++){
        getchar();
        int a,b,v;
        char q;
        //printf("^^^%d^^^\n",m);
        scanf("%c %d %d",&q,&a,&b);
        //printf("###%d###\n",m);
        if(q=='C'){
            scanf("%d",&v);
            updata(1,1,n,a,b,v);
        }
        else{
           // printf("%d %d %d&&&&&&&&&\n",a,b,m);
            printf("%I64d\n",query(1,1,n,a,b));
        }
    }
    //printf(" %d.\n",arr[1].data);
}
int main()
{

        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%I64d",&p[i]);
        build(1,1,n);
        //printf(" %d.\n",arr[1].data);
       // printf("Case %d: The total value of the hook is",i);
        solve();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值