来一波数据结构
树状数组
#include<bits/stdc++.h> using namespace std; const int MAX=5e5+5; int n,m,c[MAX]; int lowbit(int x) { return x&-x; } void update(int a,int b) { while(a<=n) { c[a]+=b; a+=lowbit(a); } } int sum(int x) { int ans=0; while(x>0) { ans+=c[x]; x-=lowbit(x); } return ans; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { int x; cin>>x; update(i,x); } for(int i=1;i<=m;i++) { int k,a,b; scanf("%d%d%d",&k,&a,&b); if(k==2) printf("%d\n",sum(b)-sum(a-1)); else update(a,b); } return 0; }
ST表(RMQ问题)
#include<bits/stdc++.h> using namespace std; const int MAX=1e6,LOG=25; int n,m; int f[MAX][LOG],logg[MAX]; inline int read() { int ans=0,f=1; char c; c=getchar(); while(c<'0' || c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9') { ans=ans*10+c-'0'; c=getchar(); } return ans*f; } void init() { n=read(),m=read(); for(int i=1;i<=n;i++) f[i][0]=read(); logg[0]=-1; for(int i=1;i<=n;i++) logg[i]=logg[i>>1]+1; } void st() { for(int j=1;j<=LOG;j++) for(int i=1;i+(1<<j)-1<=n;i++) f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]); } int main() { init(); st(); for(int i=1;i<=m;i++) { int x,y; x=read(),y=read(); int s=logg[y-x+1]; printf("%d\n",max(f[x][s],f[y-(1<<s)+1][s])); } return 0; }
线段树
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,m,a[N]; int add[N*4];//账本 long long sum[N*4];//a[k]的区间和 void build(int k,int l,int r)//建树 { if(l==r) { sum[k]=a[l]; return; } int mid=(l+r)/2; build(k*2,l,mid); build(k*2+1,mid+1,r); sum[k]=sum[k*2]+sum[k*2+1]; } void Add(int k,int l,int r,int v)//区间加值并更新 { add[k]+=v; sum[k]+=(long long)v*(r-l+1); } void pushdown(int k,int l,int r,int mid)//标记下放 { if(add[k]==0) return; Add(k*2,l,mid,add[k]); Add(k*2+1,mid+1,r,add[k]); add[k]=0; } long long query(int k,int l,int r,int x,int y)//询问 { if(l>=x && r<=y) return sum[k]; int mid=(l+r)/2; long long res=0; pushdown(k,l,r,mid); if(x<=mid) res+=query(2*k,l,mid,x,y); if(mid<y) res+=query(2*k+1,mid+1,r,x,y); return res; } void modify(int k,int l,int r,int x,int y,int v)//区间加v { if(l>=x && r<=y) return Add(k,l,r,v); int mid=(l+r)/2; pushdown(k,l,r,mid); if(x<=mid) modify(2*k,l,mid,x,y,v); if(mid<y) modify(2*k+1,mid+1,r,x,y,v); sum[k]=sum[2*k]+sum[2*k+1]; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d",a+i); build(1,1,n); while(m--) { int A,B,C,OP; scanf("%d",&OP); if(OP==1) { scanf("%d%d%d",&A,&B,&C); modify(1,1,n,A,B,C); } if(OP==2) { scanf("%d%d",&A,&B); printf("%lld\n",query(1,1,n,A,B)); } } return 0; }