好像好久没打线段树了手都生了..我再来重新打份模板(好像还没A过..23333)
题目描述
如题,已知一个数列,你需要进行下面两种操作:
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的结果。
输入输出样例
输入样例
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
输出样例
11
8
20
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^,保证在int64/long long数据范围内)
样例说明:
思路
没啥好说的,一看到区间修改和区间求和就想到线段树就行了2333
Code
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline void readInt(int &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline void readLong(ll &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
/*================Header Template==============*/
#define lson o<<1
#define rson o<<1|1
const int maxn=100010;
struct seg_tree{ll l,r,sum,lazy;}t[maxn<<2];
int n,m,type,l,r,x;
inline void pushup(int o){t[o].sum=t[lson].sum+t[rson].sum;}
inline void pushdown(int o) {
if(t[o].lazy) {
t[lson].lazy+=t[o].lazy;
t[rson].lazy+=t[o].lazy;
t[lson].sum+=t[o].lazy*(t[lson].r-t[lson].l+1);
t[rson].sum+=t[o].lazy*(t[rson].r-t[rson].l+1);
t[o].lazy=0;
}
}
inline void build(int o,int l,int r) {
// cout<<o<<" "<<l<<" "<<r<<endl;
t[o].l=l;
t[o].r=r;
if(l==r) {
readLong(t[o].sum);
return;
}
int mid=(l+r)>>1;
// cout<<mid<<endl;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(o);
}
inline void update(int o,int l,int r,int ql,int qr,ll add) {
pushdown(o);
if(t[o].l==ql&&t[o].r==qr) {
t[o].lazy+=add;
t[o].sum+=add*(qr-ql+1);
return;
}
int mid=(l+r)>>1;
if(qr<=mid)
update(lson,l,mid,ql,qr,add);
else if(ql>mid)
update(rson,mid+1,r,ql,qr,add);
else {
update(lson,l,mid,ql,mid,add);
update(rson,mid+1,r,mid+1,qr,add);
}
pushup(o);
}
inline ll query(int o,int l,int r,int ql,int qr) {
pushdown(o);
if(l==ql&&r==qr)
return t[o].sum;
int mid=(l+r)>>1;
if(qr<=mid)
return query(lson,l,mid,ql,qr);
else if(ql>mid)
return query(rson,mid+1,r,ql,qr);
else
return query(lson,l,mid,ql,mid)+query(rson,mid+1,r,mid+1,qr);
}
int main() {
readInt(n);
readInt(m);
build(1,1,n);
while(m--) {
readInt(type);
if(type==1) {
readInt(l);
readInt(r);
readInt(x);
update(1,1,n,l,r,x);
}
else {
readInt(l);
readInt(r);
printf("%lld\n",query(1,1,n,l,r));
}
}
return 0;
}