P3372 【模板】线段树 1
线段树
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
int n,m;
long long a[MAXN],tree[MAXN*4],lazy[MAXN*4];
//tree[] 最大是4*MAXN
//lazy[] 标记 其子节点待加lazy[],保证复杂度小于O(n)
void up(int root){ //向上传递更新
tree[root]=tree[root<<1]+tree[root<<1 | 1];
}
void down(int root,int l,int r){ //*** 向下更新tree[root<<1]和tree[root<<1 | 1] ,传递lazy[]
if(lazy[root]){
int mid=(l+r)>>1;
tree[root<<1]+=lazy[root]*(mid-l+1);
tree[root<<1 | 1]+=lazy[root]*(r-mid);
lazy[root<<1]+=lazy[root];
lazy[root<<1 | 1]+=lazy[root];
lazy[root]=0;
}
}
void build(int root,int l,int r){//建树
if(l==r){
tree[root]=a[l];
lazy[root]=0;//***赋初值,不然会错
return;
}
int mid=(l+r)>>1;
down(root,l,r);//更新不能忘
build(root<<1,l,mid);
build((root<<1)+1,mid+1,r);
up(root);// 更新不能忘
}
void add(int root,int l,int r,int ql,int qr,long long x){
if(l>=ql&&r<=qr){
tree[root]+=x*(r-l+1);
lazy[root]+=x;
return;
}
int mid=(l+r)>>1;
down(root,l,r);//更新不能忘,步步更新
if(ql<=mid) add(root<<1,l,mid,ql,qr,x);
if(qr>mid) add(root<<1 | 1,mid+1,r,ql,qr,x);
up(root);//更新不能忘,步步更新
}
long long getsum(int root,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
return tree[root];
}
int mid=(l+r)>>1;
long long res=0;
down(root,l,r);//步步更新
if(ql<=mid) res+=getsum(root<<1,l,mid,ql,qr);
if(qr>mid) res+=getsum(root<<1 | 1,mid+1,r,ql,qr);
up(root);//步步更新
return res;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
int op,x,y;
long long k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
add(1,1,n,x,y,k);
}
if(op==2){
cin>>x>>y;
cout<<getsum(1,1,n,x,y)<<"\n";
}
}
}
树状数组 :差分+2个树状数组
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
int n,m;
long long a[MAXN],ch[MAXN],tree_1[MAXN],tree_2[MAXN];
long long lowbit(long long x){
return x&(-x);
}
long long tree_1_notadd(int pos){
long long res=0;
while(pos>0){
res+=tree_1[pos];
pos-=lowbit(pos);
}
return res;
}
void tree_1_add(int pos,long long x){
while(pos<=n){
tree_1[pos]+=x;
pos+=lowbit(pos);
}
}
long long tree_2_notadd(int pos){
long long res=0;
while(pos>0){
res+=tree_2[pos];
pos-=lowbit(pos);
}
return res;
}
void tree_2_add(int pos,long long x){
while(pos<=n){
tree_2[pos]+=x;
pos+=lowbit(pos);
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
ch[1]=a[1];
tree_1_add(1,ch[1]);
tree_2_add(1,ch[1]);
for(int i=2;i<=n;i++){
ch[i]=a[i]-a[i-1];
tree_1_add(i,ch[i]);
tree_2_add(i,ch[i]*i);
}
while(m--){
int op;
long long k;
int x,y;
cin>>op;
if(op==1){
cin>>x>>y>>k;
tree_1_add(x,k);
tree_1_add(y+1,-k);
tree_2_add(x,1ll*k*x);
tree_2_add(y+1,1ll*-k*(y+1));
}
if(op==2){
cin>>x>>y;
long long high=1ll*(y+1)*tree_1_notadd(y)-tree_2_notadd(y);
long long low=1ll*(x)*tree_1_notadd(x-1)-tree_2_notadd(x-1);
cout<<high-low<<"\n";
//cout<<1<<"\n";
}
}
}
加油!!