题目连接: 【模板】树状数组 2
写这个题是打算学习差分的,所以就没写线段树和树状数组。
差分
来自: Snitro
设 数 组 a [ ] = { 1 , 6 , 8 , 5 , 10 } , 那 么 差 分 数 组 b [ ] = { 1 , 5 , 2 , − 3 , 5 } 设数组a[\ ]=\{1,6,8,5,10\},那么差分数组b[\ ]=\{1,5,2,-3,5\} 设数组a[ ]={1,6,8,5,10},那么差分数组b[ ]={1,5,2,−3,5}
也 就 是 说 b [ i ] = a [ i ] − a [ i − 1 ] ( a [ 0 ] = 0 ) , 那 么 a [ i ] = b [ 1 ] + . . . . + b [ i ] 也就是说b[i]=a[i]-a[i-1] (a[0]=0),那么a[i]=b[1]+....+b[i] 也就是说b[i]=a[i]−a[i−1](a[0]=0),那么a[i]=b[1]+....+b[i](这个很好证的)。
假 如 区 间 [ 2 , 4 ] 都 加 上 2 的 话 假如区间[2,4]都加上2的话 假如区间[2,4]都加上2的话
a 数 组 变 为 a [ ] = { 1 , 8 , 10 , 7 , 10 } , b 数 组 变 为 b [ ] = { 1 , 7 , 2 , − 3 , 3 } ; a数组变为a[\ ]=\{1,8,10,7,10\},b数组变为b[\ ]=\{1,7,2,-3,3\}; a数组变为a[ ]={1,8,10,7,10},b数组变为b[ ]={1,7,2,−3,3};
发 现 了 没 有 , b 数 组 只 有 b [ 2 ] 和 b [ 5 ] 变 了 , 因 为 区 间 [ 2 , 4 ] 是 同 时 加 上 2 的 , 所 以 在 区 间 内 b [ i ] − b [ i − 1 ] 是 不 变 的 . 发现了没有,b数组只有b[2]和b[5]变了,因为区间[2,4]是同时加上2的,所以在区间内b[i]-b[i-1]是不变的. 发现了没有,b数组只有b[2]和b[5]变了,因为区间[2,4]是同时加上2的,所以在区间内b[i]−b[i−1]是不变的.
所 以 对 区 间 [ x , y ] 进 行 修 改 , 只 用 修 改 b [ x ] 与 b [ y + 1 ] : 所以对区间[x,y]进行修改,只用修改b[x]与b[y+1]: 所以对区间[x,y]进行修改,只用修改b[x]与b[y+1]:
b [ x ] = b [ x ] + k ; b [ y + 1 ] = b [ y + 1 ] − k ; b[x]=b[x]+k;b[y+1]=b[y+1]-k; b[x]=b[x]+k;b[y+1]=b[y+1]−k;
然后我照着写了一发 T 了。。。
然后又看到下面有人用树状数组维护差分数组
AC code
/*
【模板】树状数组 2
P3368
https://www.luogu.org/problem/P3368
解法: 树状数组维护差分数组
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 1000000
ll a[maxn];
ll tree[maxn<<1];
ll n,m;
inline 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-48;c=getchar();}
return x*f;
}
void update(int x,int val){
while(x<=n){
tree[x]+=val;
x+=x&(-x);
}
}
long long sum(long long x){
long long ans=0;
while(x>=1){
ans+=tree[x];
x-=x&(-x);
}
return ans;
}
int main(){
int s,l,r,x;
n=read();
m=read();
memset(tree,0,(n+1)*sizeof (ll));
for(int i=1;i<=n;i++){
a[i]=read();
update(i,a[i]-a[i-1]);
}
while(m--){
s=read();
if(s==2){
x=read();
printf("%lld\n", sum(x));
}else{
l=read();
r=read();
x=read();
update(l,x);
update(r+1,-x);
}
}
}