对于区间修改+单点查询,我们是用差分的思想去完成,一直维护一个差分数组,到时候查询的时候差分的前缀和就行了。
那么对于区间查询,我们不可能对区间中每一个点都去查询,然后相加,这样时间复杂度过不去,于是,我们就要想更加好的方法。
我们要对一个区间求和,即a1+a2+a3+…+an,即对差分数组d1+d1+d2+d1+d2+d3+…+d1+d2+…+dn,也就是nd1+(n-1)d2+…+dn;那么我们只要用另一个数组维护一下di*(i-1)就行,到时候输出区间和的时候,就对这个数组求和即可。
#include<iostream>
using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double EPS=1e-6;
typedef long long ll;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
int a[N],d[N],sum1[N],sum2[N];
int n,q;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i))
{
sum1[i]+=k;
sum2[i]+=k*(x-1);
}
}
int sum(int x)
{
int s=0;
for(int i=x;i;i-=lowbit(i))
{
s+=x*sum1[i]-sum2[i];
}
return s;
}
signed main()
{
IOS;
//freopen("","r",stdin);
//freopen("","w",stdout);
cin>>n>>q;
for(int i=1;i<=n;i++)
{
cin>>a[i];
d[i]=a[i]-a[i-1];
add(i,d[i]);
}
while(q--)
{
char ch;
cin>>ch;
if(ch=='Q')
{
int x,y;
cin>>x>>y;
cout<<sum(y)-sum(x-1)<<endl;
}
else
{
int x,y,k;
cin>>x>>y>>k;
add(x,k);
add(y+1,-k);
}
}
}