线段树模板一
题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数加上x
2.求出某区间每一个数的和
输入格式
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k
操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和
输出格式
输出包含若干行整数,即为所有操作2的结果。
输入输出样例
输入 #1
5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4
输出 #1
11 8 20
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+9; struct node{ int l,r; ll sum,lazy; }a[maxn<<2]; ll s[maxn]; inline void pushup(int k) { a[k].sum=(a[k<<1].sum+a[k<<1|1].sum); } inline void build(int k,int l,int r) { a[k].l=l,a[k].r=r; if(l==r) { a[k].sum=s[l]; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } //void change(int k,int x,int y) //{ // if(a[k].l==a[k].r) // { // a[k].sum=y;return; // } // int mid=(a[k].l+a[k].r)>>1; // if(x<=mid)change(k<<1,x,y); // else change(k<<1|1,x,y); // update(k); //} inline void pushdown(int k) { if(a[k].l==a[k].r) { a[k].lazy=0;return; } a[k<<1].sum+=(a[k<<1].r-a[k<<1].l+1)*a[k].lazy; a[k<<1|1].sum+=(a[k<<1|1].r-a[k<<1|1].l+1)*a[k].lazy; a[k<<1].lazy+=a[k].lazy; a[k<<1|1].lazy+=a[k].lazy; a[k].lazy=0; } inline void update(int k,int l,int r,int x) { if(a[k].l>=l&&a[k].r<=r) { a[k].sum+=(a[k].r-a[k].l+1)*x; a[k].lazy+=x; return; } if(a[k].lazy)pushdown(k); int mid=(a[k].l+a[k].r)>>1; if(l<=mid)update(k<<1,l,r,x); if(r>mid)update(k<<1|1,l,r,x); // else changeplus(k<<1,l,mid,x),changeplus(k<<1|1,mid+1,r,x); pushup(k); } //void changemul(int k,int l,int r,int x) //{ // //} inline ll query(int k,int l,int r) { if(a[k].lazy)pushdown(k); if(a[k].l>=l&&r>=a[k].r) { return a[k].sum; } ll ans=0; int mid=(a[k].l+a[k].r)>>1; if(l<=mid)ans+=query(k<<1,l,r); if(r>mid)ans+=query(k<<1|1,l,r); // else ans+=query(k<<1,l,mid)+query(k<<1|1,mid+1,r); return ans; } int main() { int n,m,i,L,R,c,opt; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%lld",&s[i]); build(1,1,n); while(m--) { scanf("%d",&opt); if(opt==1) { scanf("%d%d%d",&L,&R,&c); update(1,L,R,c); } else { scanf("%d%d",&L,&R); printf("%lld\n",query(1,L,R)); } } }
欢迎加我qq1165750856一起玩呀~