相比较于单点更新和单点查询来说
区间更新多了一个pushdown函数
代码如下
void pushdown(int root,int m){ if(add[root]){ add[root<<1] += add[root]; add[root<<1 | 1] += add[root]; sum[root<<1] += add[root]*(m-(m>>1)); sum[root<<1 | 1] += add[root]*(m>>1); add[root] = 0; } }假如我们要更新(2,3)区间,区间每个值加val
(2,3)区间的子区间(2,2),(3,3)就也要更新
这时我们增加一个add标记
如果(2,3)区间的每个值要加val
向下的每个区间也要加val
就有
add[root<<1] += add[root]; add[root<<1 | 1] += add[root];
之后的sum就根据这个区间的长度去更新
代码如下<pre name="code" class="cpp">/******************************************** Author :Crystal Created Time : File Name : ********************************************/ #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <climits> #include <string> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map> #include <sstream> #include <cctype> using namespace std; typedef long long ll; typedef pair<int ,int> pii; #define MEM(a,b) memset(a,b,sizeof a) #define CLR(a) memset(a,0,sizeof a); const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; //#define LOCAL int ans[500005]; ll add[500005]; ll sum[500006]; void pushup(int root){ sum[root] = sum[root*2] + sum[root*2+1]; } void pushdown(int root,int m){ if(add[root]){ add[root<<1] += add[root]; add[root<<1 | 1] += add[root]; sum[root<<1] += add[root]*(m-(m>>1)); sum[root<<1 | 1] += add[root]*(m>>1); add[root] = 0; } } void build(int l,int r,int root){ add[root] = 0; if(l == r){ scanf("%lld",&sum[root]); return; } int m = (l+r)>>1; build(l,m,root*2); build(m+1,r,root*2+1); pushup(root); return; } void update(int l,int r,int root,int ls,int rs,int val){ if(l>=ls && r <= rs){ sum[root] += (ll)val*(r-l+1); add[root] += val; return; } pushdown(root,r-l+1); int m = (l+r)>>1; if(ls <= m)update(l,m,root<<1,ls,rs,val); if(rs>m)update(m+1,r,root<<1|1,ls,rs,val); pushup(root); } ll query(int l,int r,int root,int ls,int rs){ if(l>=ls && r <= rs){ return sum[root]; } pushdown(root,r-l+1); int m = (l+r)>>1; ll res = 0; if(ls <= m)res += query(l,m,root*2,ls,rs); if(rs > m)res += query(m+1,r,root*2+1,ls,rs); return res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif int n,m; while(cin >> n >> m){ //cout << n << endl; build(1,n,1); for(int i=1;i<=m;i++){ char q[10]; scanf("%s",q); if(q[0]=='Q'){ int a,b;scanf("%d%d",&a,&b); printf("%lld\n",query(1,n,1,a,b)); } else{ int a,b,c; scanf("%d%d%d",&a,&b,&c); update(1,n,1,a,b,c); } } } return 0; }