参考博客:https://www.cnblogs.com/lcf-2000/p/5866170.html
原题:https://www.acwing.com/problem/content/description/244/
给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。
2、“Q l r”,表示询问 数列中第 l~r 个数的和。
对于每个询问,输出一个整数表示答案。
输入格式
第一行两个整数N,M。
第二行N个整数A[i]。
接下来M行表示M条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
1≤N,M≤1051≤N,M≤105,
|d|≤10000|d|≤10000,
|A[i]|≤1000000000|A[i]|≤1000000000
输入样例:
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
输出样例:
4
55
9
15
时/空限制: 1s / 64MB
#include<iostream>
#define ll long long
using namespace std;
const int N = 100000 + 10;
ll a[N],tree1[N],tree2[N];
ll n;
ll lowbit(ll x)
{
return x & -x;
}
ll query(ll x)
{
ll ans = 0;
for(ll i=x; i>=1; i-=lowbit(i))
ans += (x+1) * tree1[i] - tree2[i];
return ans;
}
void add(ll x, ll val)
{
for(int i=x; i<=n; i+=lowbit(i))
{
tree1[i] += val;
tree2[i] += x * val;//注意这里是x
}
}
int main()
{
int m;
cin>>n>>m;
for(ll i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
add(i, a[i] - a[i-1]);
}
char c;
while(m--)
{
getchar();
cin>>c;
if(c == 'Q')
{
int l,r;
cin>>l>>r;
cout<<query(r) - query(l-1)<<endl;
}
else
{
ll l, r, val;
cin>>l>>r>>val;
add(l,val);
add(r+1,(ll)-1 * val);//注意这里是r+1
}
}
return 0;
}
// 10 5
// 11 15 -12 -16 18 -8 -4 -9 16 18
// Q 7 8
// C 5 10 -4
// Q 6 6
// C 3 4 2
// Q 1 4
来源:CSDN
作者:san lolo
链接:https://blog.csdn.net/weixin_44267044/article/details/104444636