题目:http://wikioi.com/problem/1082/
思路:设某一数组f[x](初始f[x]={0})
对于某一操作:对于区间[l,r]中所有数增加c,则f[l]+=c,f[r+1]-=c,
则在任何情况下有pr[i]=(f[1]+f[2]+...+f[i])为a[i]在经过操作后的增加量
则sum(l,r)=a[l]+...+a[r]增加量为
delta=pr[l]+pr[l+1]+...+pr[r]
=(f[1]+f[2]+...+f[l])+(f[1]+f[2]+...+f[l]+f[l+1])+...+(f[1]+f[2]+...+f[r])
=(r-l+1)(f[1]+f[2]+...+f[l])+f[r]+f[r-1]2+...+f[l+1]*(r-l)
=(r-l+1)(f[1]+...+f[l])+(r-(r-1))f[r]+(r-(r-2))f[r-1]+...+(r-l)f[l+1]
=(r-l+1)(f[1]+...+f[l])+r(f[r]+...+f[l+1])-(r-1)f[r]-(r-2)f[r-1]-...-l*f[l+1]
=(r-l+1)(f[1]+...+f[l])+r(f[l+1]+...+f[r])-[lf[l+1]+(l+1)f[l+2]+...+(r-1)*f[r]]
此时区间增量由三个部分组成
分别为:
+(r-l+1)*(f[1]+...+f[l]);
+(r-l+1)*(f[1]+...+f[l]);
-[lf[l+1]+(l+1)f[l+2]+...+(r-1)*f[r]];
即动态维护f[i],(i-1)f[i]的前缀和即可快速得到区间增量*
所以
sum(l,r)=sum0(l,r)+delta
由于原序列不会变动,所以可以用前缀和来维护,
对于(f[1]+...+f[i])和((1-1)f[1]+(2-1)f[2]+...+(i-1)f[i])可以用树状数组维护。*
代码:https://www.jianshu.com/p/ed01dea8da19