链接:https://ac.nowcoder.com/acm/problem/15175
来源:牛客网
题意:
输入Q代表求从x到y的和,输入C代表从a到b位置的数都加上c
思路:
树状数组,线段树模板,区间更新,区间求和。
AC代码:
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll A[maxn],a,b,c,sum[maxn*4],add[maxn*4],n,m;
char ch;
//下推标记
void pushDown(int node,int m) {
if(add[node]) {
add[node*2] += add[node];
add[node*2+1] += add[node];
sum[node*2] += add[node]*(m-m/2);
sum[node*2+1] += add[node]*(m/2);
add[node] = 0;
}
}
//建树
void build(int l,int r,int node) {
add[node]=0;
if(l==r) {
sum[node]=A[l];
return;
}
int mid = (l+r)/2;
build(l,mid,node*2);
build(mid+1,r,node*2+1);
sum[node] = sum[node*2]+sum[node*2+1];
}
//区间修改 A[l,r] += c
void updateSegment(int l,int r,int c,int x,int y,int node) {
if(l<=x && y<=r) {
sum[node] += (ll)c*(y-x+1);
add[node] += c;
return ;
}
pushDown(node,y-x+1);
int mid = (x+y)/2;
if(l<= mid) updateSegment(l,r,c,x,mid,node*2);
if(r > mid) updateSegment(l,r,c,mid+1,y,node*2+1);
sum[node] = sum[node*2]+sum[node*2+1];
}
ll query(int l,int r,int x,int y,int node) {
if(l<=x && y<=r) return sum[node];
pushDown(node,y-x+1);
int mid = (x+y)/2;
ll ans = 0;
if(l<=mid) ans += query(l,r,x,mid,node*2);
if(r>mid) ans += query(l,r,mid+1,y,node*2+1);
return ans;
}
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++) cin>>A[i];
build(1,n,1);
while(m--) {
cin>>ch;
if(ch=='Q') {
cin>>a>>b;
cout<<query(a,b,1,n,1)<<endl;
} else {
cin>>a>>b>>c;
updateSegment(a,b,c,1,n,1);
}
}
return 0;
}