【ybtoj 高效进阶 4.2】 【树状数组】 区间修改区间查询
题目
解题思路
区间修改可以用查分
例如区间l—r,在l处加,在r+1处减,这一段的前缀和将会改变
一个数组维护加的数,一个数组维护前缀
代码
#include<iostream>
#include<cstdio>
using namespace std;
long long z,n,m,l,r,w,a[1000010],c[1000010],f[1000010];
void put(long long x,long long y)
{
for (int i=x;i<=n;i+=i&(-i))
{
c[i]+=y;
f[i]+=y*x;
}
}
long long get(long long x)
{
long long sum=0;
for (int i=x;i;i-=i&(-i))
sum+=c[i]*(x+1)-f[i];
return sum;
}
int main()
{
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
put(i,a[i]);
put(i+1,-a[i]);
}
for (int i=1;i<=m;i++)
{
scanf("%lld",&w);
if (w==1)
{
scanf("%lld%lld%lld",&l,&r,&z);
put(l,z);
put(r+1,-z);
}
else {
scanf("%lld%lld",&l,&r);
printf("%lld\n",get(r)-get(l-1));
}
}
return 0;
}