题意:一个数列,每次操作可以是将某区间数字都加上一个相同的整数,也可以是询问一个区间中所有数字的和。(这里区间指的是数列中连续的若干个数)对每次询问给出结果。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <algorithm> using namespace std; #define M 100005 #define ls node<<1,l,m #define rs node<<1|1,m+1,r int n,m; long long tree1[M<<2],tree2[M<<2]; void pushdown(int node,int m) { if(tree1[node]) { tree1[node<<1]+=tree1[node]; tree1[node<<1|1]+=tree1[node]; tree2[node<<1]+=(m-(m>>1))*tree1[node]; tree2[node<<1|1]+=(m>>1)*tree1[node]; tree1[node]=0; } } void buildtree(int node,int l,int r) { tree1[node]=0; if(l==r) { scanf("%lld",&tree2[node]); return ; } int m=(l+r)>>1; buildtree(ls); buildtree(rs); tree2[node]=tree2[node<<1]+tree2[node<<1|1]; } void update(int L,int R,int c,int node,int l,int r) { if(L<=l&&r<=R) { tree1[node]+=c; tree2[node]+=c*(r-l+1); return ; } pushdown(node,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,c,ls); if(R>m) update(L,R,c,rs); tree2[node]=tree2[node<<1]+tree2[node<<1|1]; } long long query(int node,int l,int r,int L,int R) { if(L<=l&&r<=R) { return tree2[node]; } pushdown(node,r-l+1); int m=(l+r)>>1; long long ans=0; if(L<=m) ans+=query(ls,L,R); if(R>m) ans+=query(rs,L,R); return ans; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { buildtree(1,1,n); char s[2]; int a,b,c; while(m--) { scanf("%s",s); if(s[0]=='Q') { scanf("%d%d",&a,&b); printf("%lld ",query(1,1,n,a,b)); } else { scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,1,n); } } } return 0; }