树状数组:单点修改+区间查询
#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=5e5+5;
int n,m,k,a,b,c[M];
inline int lowbit(int x){return x&(-x);}
inline void updata(int x,int y){for(;x<=n;x+=lowbit(x))c[x]+=y;}
inline int sum(int x){
int ans=0;
for(;x;x-=lowbit(x))ans+=c[x];
return ans;
}
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
int main(){
n=read(),m=read();
For(i,1,n){
updata(i,read());
}
For(i,1,m){
k=read(),a=read(),b=read();
if(k==1){
updata(a,b);
}
else{
printf("%d
",sum(b)-sum(a-1));
}
}
return 0;
}
树状数组:区间修改+单点查询
#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=5e5+5;
ll n,m,c[M],v[M],k,a,b,d,x;
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
inline int lowbit(int x){return x&(-x);}
inline void updata(int x,int y){for(;x<=n;x+=lowbit(x)){c[x]+=y;}}
inline ll sum(int x){
int ans=0;
for(;x;x-=lowbit(x)){
ans+=c[x];
}
return ans;
}
int main(){
n=read(),m=read();
For(i,1,n){
v[i]=read();
updata(i,v[i]-v[i-1]);
}
For(i,1,m){
k=read();
if(k==1){
a=read(),b=read(),d=read();
updata(a,d);updata(b+1,-d);
}
else{
x=read();
printf("%d
",sum(x));
}
}
return 0;
}
线段树:加法
#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=1e5+5;
ll n,m,a[M],k,x,y,d;
struct node{
ll l,r,lz,s;
}tr[M*4];
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
inline void B_T(int i,int l,int r){
tr[i].l=l,tr[i].r=r;
if(l==r){tr[i].s=a[l];return;}
int mid=(l+r)>>1;
B_T(i<<1,l,mid),B_T(i<<1|1,mid+1,r);
tr[i].s+=tr[i<<1].s+tr[i<<1|1].s;
}
inline void D_T(int i){
tr[i<<1].lz+=tr[i].lz;
tr[i<<1].s+=(tr[i<<1].r-tr[i<<1].l+1)*tr[i].lz;
tr[i<<1|1].lz+=tr[i].lz;
tr[i<<1|1].s+=(tr[i<<1|1].r-tr[i<<1|1].l+1)*tr[i].lz;
tr[i].lz=0;
}
inline void U_T(int i,int l,int r,int v){
if(tr[i].l>r||tr[i].r<l)return;
if(tr[i].l>=l&&tr[i].r<=r){
tr[i].lz+=v;
tr[i].s+=(tr[i].r-tr[i].l+1)*v;
return;
}
if(tr[i].lz) D_T(i);
U_T(i<<1,l,r,v),U_T(i<<1|1,l,r,v);
tr[i].s=tr[i<<1].s+tr[i<<1|1].s;
}
inline ll Q_T(int i,int l,int r){
if(tr[i].l>r||tr[i].r<l) return 0;
if(tr[i].l>=l&&tr[i].r<=r) return tr[i].s;
if(tr[i].lz) D_T(i);
return Q_T(i<<1,l,r)+Q_T(i<<1|1,l,r);
}
int main(){
n=read(),m=read();
For(i,1,n) a[i]=read();
B_T(1,1,n);
For(i,1,m){
k=read();
if(k==1){
x=read(),y=read(),d=read();
U_T(1,x,y,d);
}
else{
x=read(),y=read();
printf("%lld
",Q_T(1,x,y));
}
}
return 0;
}
线段树:乘法
#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=1e5+5;
ll n,m,p,a[M],k,x,y,d,c;
struct node{
ll l,r,s,mlz,plz;
}tr[4*M];
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
inline void B_T(ll i,ll l,ll r){
tr[i].l=l,tr[i].r=r,tr[i].mlz=1;
if(l==r){tr[i].s=a[l]%p;return;}
ll mid=(l+r)>>1;
B_T(i<<1,l,mid),B_T(i<<1|1,mid+1,r);
tr[i].s=(tr[i<<1].s+tr[i<<1|1].s)%p;
return;
}
inline void P_T(ll i){
ll k1=tr[i].mlz,k2=tr[i].plz;
tr[i<<1].s=(tr[i<<1].s*k1+(tr[i<<1].r-tr[i<<1].l+1)*k2)%p;
tr[i<<1].mlz=(tr[i<<1].mlz*k1)%p;
tr[i<<1].plz=(tr[i<<1].plz*k1+k2)%p;
tr[i<<1|1].s=(tr[i<<1|1].s*k1+(tr[i<<1|1].r-tr[i<<1|1].l+1)*k2)%p;
tr[i<<1|1].mlz=(tr[i<<1|1].mlz*k1)%p;
tr[i<<1|1].plz=(tr[i<<1|1].plz*k1+k2)%p;
tr[i].plz=0,tr[i].mlz=1;
return;
}
inline void M_T(ll i,ll l,ll r,ll d){
if(tr[i].l>r||tr[i].r<l) return;
if(tr[i].l>=l&&tr[i].r<=r){
tr[i].s=(tr[i].s*d)%p;
tr[i].mlz=(tr[i].mlz*d)%p;
tr[i].plz=(tr[i].plz*d)%p;
return;
}
P_T(i);
if(tr[i<<1].r>=l) M_T(i<<1,l,r,d);
if(tr[i<<1|1].l<=r) M_T(i<<1|1,l,r,d);
tr[i].s=(tr[i<<1].s+tr[i<<1|1].s)%p;
return;
}
inline void A_T(ll i,ll l,ll r,ll d){
if(tr[i].l>r||tr[i].r<l)return;
if(tr[i].l>=l&&tr[i].r<=r){
tr[i].s+=((tr[i].r-tr[i].l+1)*d)%p;
tr[i].plz=(tr[i].plz+d)%p;
return;
}
P_T(i);
if(tr[i<<1].r>=l) A_T(i<<1,l,r,d);
if(tr[i<<1|1].l<=r) A_T(i<<1|1,l,r,d);
tr[i].s=(tr[i<<1].s+tr[i<<1|1].s)%p;
return;
}
inline ll Q_T(ll i,ll l,ll r){
if(tr[i].r<l||tr[i].l>r)return 0;
if(tr[i].r<=r&&tr[i].l>=l) return tr[i].s;
P_T(i);
ll sum=0;
if(tr[i<<1].r>=l) sum+=Q_T(i<<1,l,r)%p;
if(tr[i<<1|1].l<=r) sum+=Q_T(i<<1|1,l,r)%p;
return sum%p;
}
int main(){
n=read(),m=read(),p=read();
For(i,1,n) a[i]=read();
B_T(1,1,n);
For(i,1,m){
k=read();
if(k==1){
x=read(),y=read(),c=read()%p;
M_T(1,x,y,c);
}
else if(k==2){
x=read(),y=read(),c=read()%p;
A_T(1,x,y,c);
}
else{
x=read(),y=read();
printf("%lld
",Q_T(1,x,y));
}
}
return 0;
}
线段树:开根号
#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=1e5+5;
struct node{
ll l,r,lz,s,maxx,minn;
}tr[M*4];
ll n,m,a[M],k,x,y;
inline ll read(){
ll f=1,sum=0;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
return f*sum;
}
inline void B_T(int i,int l,int r){
tr[i].l=l,tr[i].r=r;
if(l==r){tr[i].s=tr[i].minn=tr[i].maxx=a[l];return;}
int mid=(l+r)>>1;
B_T(i<<1,l,mid),B_T(i<<1|1,mid+1,r);
tr[i].s=tr[i<<1].s+tr[i<<1|1].s;
tr[i].minn=min(tr[i<<1].minn,tr[i<<1|1].minn);
tr[i].maxx=max(tr[i<<1].maxx,tr[i<<1|1].maxx);
return;
}
inline void P_T(int i){
ll k=tr[i].lz;
tr[i<<1].lz+=k;
tr[i<<1].s-=(tr[i<<1].r-tr[i<<1].l+1)*k;
tr[i<<1].minn-=k;
tr[i<<1].maxx-=k;
tr[i<<1|1].lz+=k;
tr[i<<1|1].s-=(tr[i<<1|1].r-tr[i<<1|1].l+1)*k;
tr[i<<1|1].minn-=k;
tr[i<<1|1].maxx-=k;
tr[i].lz=0;
return;
}
inline void S_T(int i,int l,int r){
if(tr[i].r<l||tr[i].l>r)return;
if(tr[i].l>=l&&tr[i].r<=r&&(tr[i].minn-(ll)sqrt(tr[i].minn))==(tr[i].maxx-(ll)sqrt(tr[i].maxx))){
ll k=tr[i].minn-(ll)sqrt(tr[i].minn);
tr[i].lz+=k;
tr[i].s-=(tr[i].r-tr[i].l+1)*k;
tr[i].minn-=k;
tr[i].maxx-=k;
return;
}
if(tr[i].lz) P_T(i);
if(tr[i<<1].r>=l) S_T(i<<1,l,r);
if(tr[i<<1|1].l<=r) S_T(i<<1|1,l,r);
tr[i].s=tr[i<<1].s+tr[i<<1|1].s;
tr[i].minn=min(tr[i<<1].minn,tr[i<<1|1].minn);
tr[i].maxx=max(tr[i<<1].maxx,tr[i<<1|1].maxx);
return;
}
inline ll Q_T(int i,int l,int r){
if(tr[i].l>r||tr[i].r<l) return 0;
if(tr[i].l>=l&&tr[i].r<=r) return tr[i].s;
if(tr[i].lz) P_T(i);
ll ans=0;
if(tr[i<<1].r>=l) ans+=Q_T(i<<1,l,r);
if(tr[i<<1|1].l<=r) ans+=Q_T(i<<1|1,l,r);
return ans;
}
int main(){
n=read();
For(i,1,n) a[i]=read();
B_T(1,1,n);
m=read();
For(i,1,m){
k=read(),x=read(),y=read();
if(x>y) swap(x,y);
if(k==1){
printf("%lld
",Q_T(1,x,y));
}
else{
S_T(1,x,y);
}
}
return 0;
}