带修改的区间最大子段和
维护一个带有两个操作的数据结构:
1.询问[L,R]之间的最大子段和
2.单点修改
题解:
正解:线段树/平衡树
线段树做法:
维护三个东西vl,vr,max,sum:
vl,vr分别表示必须包含区间左\右端点的最大子段和,max为该区间的最大子段和,sum为区间和
然后转移三个变量:
Tree[node].max=max(Tree[ls].max,max(Tree[rs].max,Tree[ls].vr+Tree[rs].vl))
Tree[node].sum=Tree[ls].sum+Tree[rs].sum
Tree[node].vl=max(Tree[ls].vl,Tree[ls].sum+Tree[rs].vl)
Tree[node].vr=max(Tree[rs].vr,Tree[rs].sum+Tree[ls].vr)
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #define ls (node<<1) 8 #define rs (node<<1|1) 9 using namespace std; 10 const int N=500005,inf=2e8; 11 int n,m,a[N]; 12 struct Segtree{ 13 int max,vl,vr,sum,fg; 14 }Tree[N<<3]; 15 void updata(int node){ 16 Tree[node].max=max(Tree[ls].max,max(Tree[rs].max,Tree[ls].vr+Tree[rs].vl)); 17 Tree[node].sum=Tree[ls].sum+Tree[rs].sum; 18 Tree[node].vl=max(Tree[ls].vl,Tree[ls].sum+Tree[rs].vl); 19 Tree[node].vr=max(Tree[rs].vr,Tree[rs].sum+Tree[ls].vr); 20 } 21 void build(int l,int r,int node){ 22 Tree[node].fg=true; 23 if(l==r){ 24 Tree[node].sum=a[l]; 25 Tree[node].max=a[l]; 26 Tree[node].vl=a[l]; 27 Tree[node].vr=a[l]; 28 return ; 29 } 30 int mid=(l+r)>>1; 31 build(l,mid,ls);build(mid+1,r,rs); 32 updata(node); 33 } 34 void add(int l,int r,int node,int ps,int to){ 35 if(l>ps || r<ps)return ; 36 if(l==r){ 37 Tree[node].sum=to; 38 Tree[node].max=to; 39 Tree[node].vl=to; 40 Tree[node].vr=to; 41 return ; 42 } 43 int mid=(l+r)>>1; 44 add(l,mid,ls,ps,to);add(mid+1,r,rs,ps,to); 45 updata(node); 46 } 47 Segtree query(int l,int r,int node,int sa,int se){ 48 if(sa<=l && r<=se)return Tree[node]; 49 int mid=(l+r)>>1; 50 if(sa>mid)return query(mid+1,r,rs,sa,se); 51 if(se<=mid)return query(l,mid,ls,sa,se); 52 Segtree t,lson,rson; 53 lson=query(l,mid,ls,sa,se);rson=query(mid+1,r,rs,sa,se); 54 t.vl=max(lson.vl,lson.sum+rson.vl);t.vr=max(rson.vr,lson.vr+rson.sum); 55 t.max=max(lson.vr+rson.vl,max(lson.max,rson.max)); 56 return t; 57 } 58 void work() 59 { 60 scanf("%d%d",&n,&m); 61 for(int i=1;i<=n;i++) 62 scanf("%d",&a[i]); 63 build(1,n,1); 64 int fg,x,y; 65 while(m--){ 66 scanf("%d%d%d",&fg,&x,&y); 67 if(fg==2)add(1,n,1,x,y); 68 else printf("%d\n",query(1,n,1,x,y).max); 69 } 70 } 71 72 int main() 73 { 74 work(); 75 return 0; 76 }