https://www.luogu.org/problem/P2824
题目描述
如题,已知一个数列,你需要进行下面两种操作:
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
说明/提示
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^,保证在int64/long long数据范围内)
样例说明:
延迟标记:该节点的值已修改,但其左右子节点尚未更新。
#include<iostream> #include<cstdio> #define ri register int #define u long long namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 100005 namespace xds { struct node { u l,r,sum,add; } a[NN<<2]; u b[NN]; void build(const u &rt,const u &l,const u &r) { a[rt].l=l,a[rt].r=r; if(l==r) { a[rt].sum=b[l]; return; } u mid(l+r>>1),_x(rt<<1),_y(rt<<1|1); build(_x,l,mid); build(_y,mid+1,r); a[rt].sum=a[_x].sum+a[_y].sum; } void pushdown(const u &rt) { if(a[rt].add) { u _x(rt<<1),_y(rt<<1|1); a[_x].sum+=(a[_x].r-a[_x].l+1)*a[rt].add; a[_y].sum+=(a[_y].r-a[_y].l+1)*a[rt].add; a[_x].add+=a[rt].add,a[_y].add+=a[rt].add; a[rt].add=0; } } void update(const u &rt,const u &l,const u &r,const u &x) { if(a[rt].l>=l&&a[rt].r<=r) { a[rt].sum+=(a[rt].r-a[rt].l+1)*x; a[rt].add+=x; return; } pushdown(rt); u _x(rt<<1),_y(rt<<1|1); if(l<=a[_x].r) update(_x,l,r,x); if(r>=a[_y].l) update(_y,l,r,x); a[rt].sum=a[_x].sum+a[_y].sum; } u query(const u &rt,const u &l,const u &r) { if(a[rt].l>=l&&a[rt].r<=r) return a[rt].sum; pushdown(rt); u _x(rt<<1),_y(rt<<1|1),_re(0); if(l<=a[_x].r) _re+=query(_x,l,r); if(r>=a[_y].l) _re+=query(_y,l,r); return _re; } } namespace mainstay { inline void solve() { u N(in()),M(in()); for(ri i(1); i<=N; ++i) xds::b[i]=in(); xds::build(1,1,N); for(ri i(1); i<=M; ++i) { u k(in()); if(k==1) { u l(in()),r(in()),_x(in()); xds::update(1,l,r,_x); } else { u l(in()),r(in()); printf("%lld ",xds::query(1,l,r)); } } } } int main() { //freopen("x.txt","r",stdin); std::ios::sync_with_stdio(false); mainstay::solve(); }