[tem]树状数组

时间:2023-03-08 23:33:44
[tem]树状数组

通过差分可以玩区间:

bi=ai-a(i-1)

查询时考虑位置对答案的贡献 推导一下

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5; ll n,a[N],b[N],c1[N],c2[N]; //basic
inline int lowbit(int x){return x&-x;}
ll sum(ll *c,int x){
ll ret=;
for(;x>;x-=lowbit(x)) ret+=c[x];
return ret;
}
ll query(ll *c,int l,int r){
return sum(c,r)-sum(c,l-);
}
void addPoint(ll *c,int x,ll v){
for(;x<=n;x+=lowbit(x)) c[x]+=v;
}
void build(ll *c,ll *a,ll n){
for(int i=;i<=n;i++){
c[i]+=a[i];
if(i+lowbit(i)<=n)
c[i+lowbit(i)]+=c[i]; //!!c[i] or while
}
} //interval-interval
void initB(ll *b,ll *a){
b[]=a[];
for(int i=;i<=n;i++) b[i]=a[i]-a[i-];
}
void addRange(int l,int r,ll v){
addPoint(c1,l,v); addPoint(c2,l,v*l);
addPoint(c1,r+,-v); addPoint(c2,r+,-v*(r+));
}
ll sumRange(int l,int r){
return query(c1,,l)*(r-l+)+ query(c1,l+,r)*(r+) -query(c2,l+,r);
} int t,l,r;
ll v;
int main(){ //freopen("in.txt","r",stdin);
//freopen("1.txt","w",stdout); cin>>n>>t;
for(int i=;i<=n;i++) cin>>a[i];
// for(int i=1;i<=n;i++){
// addRange(i,i,a[i]);
// } initB(b,a);
build(c1,b,n);
for(int i=;i<=n;i++) b[i]*=i;
build(c2,b,n); while(t--){
int flag;
cin>>flag;
if(flag==){
cin>>l>>r;
cout<<sumRange(l,r)<<"\n";
}else{
cin>>l>>r>>v;
addRange(l,r,v);
cout<<sumRange(l,r)<<"\n";
}
}
}