1.单点修改 区间查询

const int MAXN=1e5+8;
typedef long long ll;
int n;
ll a[MAXN];
inline int lowbit(int x){return x&(-x);}
inline void add(int x,ll val){//单点修改
   while(x){
  	 	a[x]+=val;
	   	x+=lowbit(x);
   	}
}
inline ll sum(int x){//返回a[x]前缀和
    ll res=0;
    while(x){
    	res+=d[x];
    	x-=lowbit(x);
    }
    return res;
}
inline ll range_sum(int x,int y){//返回区间和
	return sum[y]-sum[x-1];
}

2.区间修改 单点查询

差分数组 d [ i ] = a [ i ] a [ i 1 ] d[i]= a[i]- a[i-1] d[i]=a[i]a[i1],故 a [ i ] = d [ 1 ] + d [ 2 ] + . . . + d [ i ] a[i]=d[1]+d[2]+...+d[i] a[i]=d[1]+d[2]+...+d[i]
维护 d [ i ] d[i] d[i] 前缀和即可维护 a [ i ] a[i] a[i]
d [ i ] + = k d[i]+=k d[i]+=k 则: a [ j ] = d [ 1 ] + d [ 2 ] + . . . + d [ j ] = a [ j ] + k a[j]'=d[1]+d[2]+...+d[j] = a[j]+k a[j]=d[1]+d[2]+...+d[j]=a[j]+k 其中 ( i j ) (i\le j) (ij)
故区间 [ l , r ] [l , r ] [l,r]上加上k 等价于 d [ l ] + k d [ r + 1 ] k d[l]+k,d[r+1]-k d[l]+kd[r+1]k

const int MAXN=1e5+8;
typedef long long ll;
int n;
ll d[MAXN];//差分数组
inline int lowbit(int x){return x&(-x);}
inline void add(int x,ll val){
   while(x){
  	 	d[x]+=val;
	   	x+=lowbit(x);
   	}
}
inline void range_add(int x,int y,ll val){//区间修改
    add(x,val);
    add(y+1,-val);
}
inline ll ask(int x){//返回a[x]
    ll res=0;
    while(x){
    	res+=d[x];
    	x-=lowbit(x);
    }
    return res;
}

3.区间修改 区间查询

d [ i ] = a [ i ] a [ i 1 ] d[i]= a[i]- a[i-1] d[i]=a[i]a[i1]
d d [ i ] = i d [ i ] dd[i]=i*d[i] dd[i]=id[i]
数组a前缀和 i = 0 k a [ i ] = a [ 1 ] + a [ 2 ] + . . . + a [ k ] = i d [ 1 ] + ( i 1 ) d [ 2 ] + . . . + d [ k ] \sum_{i=0}^k a[i]=a[1]+a[2]+...+a[k]=id[1]+(i-1)d[2]+...+d[k] i=0ka[i]=a[1]+a[2]+...+a[k]=id[1]+(i1)d[2]+...+d[k]
= ( k + 1 ) ( d [ 1 ] + d [ 2 ] + . . . + d [ k ] ) ( d [ 1 ] + 2 d [ 2 ] + . . . + k d [ k ] ) =(k+1)*(d[1]+d[2]+...+d[k])-(d[1]+2d[2]+...+kd[k] ) =(k+1)(d[1]+d[2]+...+d[k])(d[1]+2d[2]+...+kd[k])
所以,维护 d [ i ] d[i] d[i] d d [ i ] dd[i] dd[i] 即可。

const int MAXN=1e5+8;
typedef long long ll;
int n;
ll d[MAXN],dd[MAXN];
inline int lowbit(int x){return x&(-x);}
inline void add(int x,ll val){//d和dd单点修改
    for(int i=x;i<=n;i+=lowbit(i)){
        d[i]+=val,dd[i]+=val*x;
    }
}
inline void range_add(int x,int y,ll val){
	add(x,val);
	add(y+1.-val);
}
inline ll sum(int x){//前缀和
    ll res=0;
    for(int i=x;i;i-=lowbit(i))
        res+=(x+1)*d[i]-dd[i];
    return res;
}
inline ll range_sum(int x,int y){
	return sum(y)-sum(x-1);
}