例题链接
题解:
利用树状数组进行区间查询,区间更新,需要利用差分的思想。定义两个数组sum1[ ] sum2[ ]
,进行差分,其实是利用树状数组的特殊结构进行求前缀和
void lowbit(int x)
{
return x&(-x);
}
update(int i,int k)
{
int x=i;
while(i<=n)
{
sum1[i]+=k;
sum2[i]+=(x-1)*k;
i+=lowbit(i);
}
}
getsum(int i)
{
int res=0,x=i;
while(i>0)
{
res+=sum1[i]*k-sum2[i];
i-=lowbit(i);
}
retrun res;
}
//注意:输入时候的update(i,a[i]-a[i-1])值的更新需要差分
ac代码:
#include<cstdio>
using namespace std;
#define maxn 100005
#define ll long long
//差分数组维护区间
ll a[maxn],sum1[maxn],sum2[maxn];
ll n,m;
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll i,ll k)
{
ll x=i;
while(i<=n)
{
sum1[i]+=k;
sum2[i]+=k*(x-1);
i+=lowbit(i);
}
}
ll getsum(ll i)
{
ll res=0,x=i;
while(i>0)
{
res+=x*sum1[i]-sum2[i];
i-=lowbit(i);
}
return res;
}
int main()
{
char s[10];
scanf("%lld %lld",&n,&m);
for(ll i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
update(i,a[i]-a[i-1]);
}
while(m--)
{
scanf("%s",s);
ll l,r,k;
if(s[0]=='C')
{
scanf("%lld %lld %lld",&l,&r,&k);
update(l,k);
update(r+1,-k);
}
else
{
scanf("%lld %lld",&l,&r);
printf("%lld\n",getsum(r)-getsum(l-1));
}
}
}