前言
我好菜啊,竟然不会树状数组区间加的操作。
讲解
普通树状数组
对于原数列 (a),树状数组 (t[n]=sum_{i={n-lowbit(n)}+1}^n a[i])
进阶树状数组
考虑差分实现区间加和询问
(t[n]=a[n]-a[n-1]Rightarrow a[n]=sum_{i=1}^n t[i])
(sum_{i=1}^na[i]=sum_{i=1}^n(n-i+1)t[i]=n*sum_{i=1}^nt[i]-sum_{i=1}^n(i-1)*t[i])
真不戳,看代码吧~
练习
代码
LL t1[MAXN],t2[MAXN];
int lowbit(int x){return (x & -x);}
void Add(int x,LL val){for(int i = x;i <= n;i += lowbit(i)) t1[i] += val,t2[i] += (x-1) * val;}
void Add(int l,int r,LL val){Add(l,val); Add(r+1,-val);}
LL Sum(int x){LL ret = 0;for(int i = x;i >= 1;i -= lowbit(i)) ret += x * t1[i] - t2[i];return ret;}//前缀和!
LL Sum(int l,int r){return Sum(r) - Sum(l-1);}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); m = Read();
for(int i = 1;i <= n;++ i) Add(i,i,Read());
while(m --> 0)
{
int opt = Read(),l = Read(),r = Read();
if(opt == 1) Add(l,r,Read());
else Put(Sum(l,r),'
');
}
return 0;
}