POJ3468 区间加,区间求和 线段树模板

来源:互联网 发布:剑灵克劳德捏脸数据图 编辑:程序博客网 时间:2024/05/22 14:52

好久没写线段树了,手有点生。。。更新的时候居然忘了更新sum集。。。最近要多练练线段树了。。。


#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <string>using namespace std;const int maxn = 100005;typedef long long ll;ll addv[maxn<<2];ll sumv[maxn<<2];ll a[maxn];int n,q;int x1,x2;ll init(int v,int l,int r){if(l==r){return sumv[v] = a[l];}int mid = (l+r)>>1;int chl = 2*v+1;int chr = chl+1;return sumv[v] = init(chl,l,mid) + init(chr,mid+1,r);}void add(int v,int l,int r,ll val){if(l>x2 || r<x1)return;if(x1<=l&&x2>=r){addv[v] += val;sumv[v] += val * (r-l+1);return;}int mid = (l+r)>>1;int chl = v*2+1;int chr = chl + 1;if(mid>=x1)add(chl,l,mid,val);if(mid<x2)add(chr,mid+1,r,val);sumv[v] = sumv[chl] + sumv[chr] + addv[v] * (r-l+1); }ll query(int v,int l,int r,ll d){if(l>x2 || r<x1)return 0;if(x1<=l&&x2>=r){return sumv[v] + d * (r-l+1); }int mid = (l+r)>>1;int chl = v*2+1;int chr = chl + 1;return query(chl,l,mid,addv[v]+d) + query(chr,mid+1,r,addv[v]+d);}int main(){int i,j;scanf("%d%d",&n,&q);for(i=0;i<n;i++){scanf("%lld",&a[i]);}char s[10];init(0,0,n-1);for(i=0;i<q;i++){scanf("%s%d%d",s,&x1,&x2);x1--;x2--;if(strcmp(s,"C")==0){int d;scanf("%lld",&d);add(0,0,n-1,d);}else{printf("%lld\n",query(0,0,n-1,0));}}return 0;}


0 0
原创粉丝点击