在一般的情况下,对于区间加与区间求和,我们一般使用线段树。
树状数组在一般情况下,只能够单点查询,修改。
但是我们可以通过差分做到区间加或者区间求和(一维)
我们对于一个区间l,r,要求他们的和a[l]….a[r]。
设b[i]表示相邻两点之间的差(b[i]=a[i]-a[i-1]),那么对于sum(a[l]..a[r])
明显有sum(a[l]..a[r])=(b[1]+b[2]+….+b[l])+(b[1]+……b[l+1])+…..+(b[1]+…..b[r])
为了方便起见假设l=1,r=n,那么上面的式子可以化简为:
sum(b[1]…b[n])*(n+1)-sum(b[1]*1+b[2]*2+…b[n]*n)
至于为什么,自己手动化一下就知道了。
然后就把区间求和转化为维护单点的前缀和与b[i]*i.
区间加的原理相同,只不过把b的定义从差值改为增量而已。
代码如下,来自
http://www.cnblogs.com/zcyhhh/p/7142676.html?utm_source=itdadao&utm_medium=referral
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
long long n,m;
long long c1[200011],c2[200011];
long long a[200011],b[200011];
long long read()
{
long long x=0,f=1;char c=getchar();
while (!isdigit(c)) {
if (c=='-')f=-1;c=getchar();}
while (isdigit(c)) {x=x*10+c-'0';c=getchar();}
return x*f;
}
long long lowbit(long long x)
{
return x&-x;
}
void update1(long long pos,