线段树
Posted liusu123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 1000010 using namespace std; int n,m,a[N]; int mx[N*4],mn[N*4]; void pushup(int k) { mx[k]=max(mx[k*2],mx[k*2+1]); mn[k]=min(mn[k*2],mn[k*2+1]); } void build(int k,int l,int r) { if(l==r) { mx[k]=mn[k]=a[l]; return; } int mid=l+r>>1; build(k*2,l,mid); build(k*2+1,mid+1,r); pushup(k); } int ask_max(int k,int l,int r,int z,int y) { if(l==z&&r==y) return mx[k]; int mid=l+r>>1; if(y<=mid) return ask_max(k*2,l,mid,z,y); if(z>mid) return ask_max(k*2+1,mid+1,r,z,y); return max(ask_max(k*2,l,mid,z,mid), ask_max(k*2+1,mid+1,r,mid+1,y)); } int ask_min(int k,int l,int r,int z,int y) { if(l==z&&r==y) return mn[k]; int mid=l+r>>1; if(y<=mid) return ask_min(k*2,l,mid,z,y); if(z>mid) return ask_min(k*2+1,mid+1,r,z,y); return min(ask_min(k*2,l,mid,z,mid), ask_min(k*2+1,mid+1,r,mid+1,y)); } void change(int k,int l,int r,int x) { if(l==r) { mx[k]=mn[k]=a[l]; return; } int mid=l+r>>1; if(x<=mid) change(k*2,l,mid,x); else change(k*2+1,mid+1,r,x); pushup(k); } int main() { cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); while(m--) { int l,r; cin>>l>>r; int ans=ask_max(1,1,n,l,r)-ask_min(1,1,n,l,r); cout<<ans<<endl; } }
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 1000010 using namespace std; int n,m,a[N]; int sum[N*4],len[N*4],ad[N*4]; void pushup(int k) { sum[k]=sum[k*2]+sum[k*2+1]; len[k]=len[k*2]+len[k*2+1]; } void A(int k,int x) { sum[k]+=x*len[k]; ad[k]+=x; } void pushdown(int k) { A(k*2,ad[k]); A(k*2+1,ad[k]); ad[k]=0; } void build(int k,int l,int r) { if(l==r) { sum[k]=a[l]; len[k]=1; return; } int mid=l+r>>1; build(k*2,l,mid); build(k*2+1,mid+1,r); pushup(k); } int ask_sum(int k,int l,int r,int z,int y) { if(l==z&&r==y) return sum[k]; if(ad[k]) pushdown(k); int mid=l+r>>1; if(y<=mid) return ask_sum(k*2,l,mid,z,y); if(z>mid) return ask_sum(k*2+1,mid+1,r,z,y); return ask_sum(k*2,l,mid,z,mid)+ ask_sum(k*2+1,mid+1,r,mid+1,y); } void change(int k,int l,int r,int z,int y,int x) { if(l==z&&r==y) { A(k,x); return; } if(ad[k]) pushdown(k); int mid=l+r>>1; if(y<=mid) change(k*2,l,mid,z,y,x); else if(z>mid) change(k*2+1,mid+1,r,z,y,x); else { change(k*2,l,mid,z,mid,x); change(k*2+1,mid+1,r,mid+1,y,x); } pushup(k); } int main() { cin>>n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); cin>>m; while(m--) { int op,a,b,x; cin>>op>>a>>b; if(op==1) { cin>>x; change(1,1,n,a,b,x); } else { int ans=ask_sum(1,1,n,a,b); cout<<ans<<endl; } } }
以上是关于线段树的主要内容,如果未能解决你的问题,请参考以下文章