GSS1
直接维护静态区间和即可
#include<bits/stdc++.h> using namespace std; const int N=50005; int n,a[N]; struct Seg_Tree{int lmax,rmax,dat,sum;}tr[N<<2]; inline void pushup(int k){ tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].lmax=max(tr[k<<1].lmax,tr[k<<1].sum+tr[k<<1|1].lmax); tr[k].rmax=max(tr[k<<1|1].rmax,tr[k<<1|1].sum+tr[k<<1].rmax); tr[k].dat=max(max(tr[k<<1].dat,tr[k<<1|1].dat),tr[k<<1].rmax+tr[k<<1|1].lmax); } inline void build(int k,int l,int r){ if(l==r)return tr[k].lmax=tr[k].rmax=tr[k].dat=tr[k].sum=a[l],void(); int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } inline Seg_Tree query(int k,int l,int r,int x,int y){ if(x<=l&&r<=y)return tr[k]; int mid=(l+r)>>1; if(x>mid)return query(k<<1|1,mid+1,r,x,y); if(y<=mid)return query(k<<1,l,mid,x,y); Seg_Tree a=query(k<<1,l,mid,x,y),b=query(k<<1|1,mid+1,r,x,y),ans; ans.sum=a.sum+b.sum; ans.lmax=max(a.lmax,a.sum+b.lmax); ans.rmax=max(b.rmax,b.sum+a.rmax); ans.dat=max(max(a.dat,b.dat),a.rmax+b.lmax); return ans; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); int q,l,r; scanf("%d",&q); while(q--){ scanf("%d%d",&l,&r); printf("%d ",query(1,1,n,l,r).dat); } }
GSS3
加入单点查询就好了
#include<bits/stdc++.h> using namespace std; const int N=50005; int n,a[N]; struct Seg_Tree{int lmax,rmax,dat,sum;}tr[N<<2]; inline void pushup(int k){ tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].lmax=max(tr[k<<1].lmax,tr[k<<1].sum+tr[k<<1|1].lmax); tr[k].rmax=max(tr[k<<1|1].rmax,tr[k<<1|1].sum+tr[k<<1].rmax); tr[k].dat=max(max(tr[k<<1].dat,tr[k<<1|1].dat),tr[k<<1].rmax+tr[k<<1|1].lmax); } inline void build(int k,int l,int r){ if(l==r)return tr[k].lmax=tr[k].rmax=tr[k].dat=tr[k].sum=a[l],void(); int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } inline Seg_Tree query(int k,int l,int r,int x,int y){ if(x<=l&&r<=y)return tr[k]; int mid=(l+r)>>1; if(x>mid)return query(k<<1|1,mid+1,r,x,y); if(y<=mid)return query(k<<1,l,mid,x,y); Seg_Tree a=query(k<<1,l,mid,x,y),b=query(k<<1|1,mid+1,r,x,y),ans; ans.sum=a.sum+b.sum; ans.lmax=max(a.lmax,a.sum+b.lmax); ans.rmax=max(b.rmax,b.sum+a.rmax); ans.dat=max(max(a.dat,b.dat),a.rmax+b.lmax); return ans; } inline void change(int k,int l,int r,int x,int v){ if(x>r||x<l)return; if(l==r&&l==x)return tr[k].lmax=tr[k].rmax=tr[k].dat=tr[k].sum=v,void(); int mid=(l+r)>>1; change(k<<1,l,mid,x,v); change(k<<1|1,mid+1,r,x,v); pushup(k); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); int q,t,l,r; scanf("%d",&q); while(q--){ scanf("%d%d%d",&t,&l,&r); if(t)printf("%d ",query(1,1,n,l,r).dat); else change(1,1,n,l,r); } }