虽然是看的别的人思路,但是做出来还是挺高兴的。
首先求环上最大字段和,而且不能是含有全部元素。本来我的想法是n个元素变为2*n个元素那样做的,这样并不好弄。实际可以求出最小值,总和-最小,就可以求出,断开的情况了。
然后线段树要单点更新,这种标记,以前遇到过,不过一直没有写过,注意总和好更新,整个这一段的结果也很好更新,最难想的就是左边 和右边标记的结果,具体看pushup代码。
1 #include <cstring> 2 #include <cstdio> 3 #include <string> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 using namespace std; 9 #define maxn 100100 10 struct node 11 { 12 int sum,lmax,lmin,rmin,rmax; 13 int smax,smin; 14 }p[4*maxn]; 15 void pushup(int rt) 16 { 17 p[rt].sum = p[rt<<1].sum + p[rt<<1|1].sum; 18 p[rt].smax = max(max(p[rt<<1].smax,p[rt<<1|1].smax),p[rt<<1].rmax+p[rt<<1|1].lmax); 19 p[rt].lmax = max(p[rt<<1].lmax,p[rt<<1].sum+p[rt<<1|1].lmax); 20 p[rt].rmax = max(p[rt<<1|1].rmax,p[rt<<1|1].sum+p[rt<<1].rmax); 21 p[rt].smin = min(min(p[rt<<1].smin,p[rt<<1|1].smin),p[rt<<1].rmin + p[rt<<1|1].lmin); 22 p[rt].lmin = min(p[rt<<1].lmin,p[rt<<1].sum+p[rt<<1|1].lmin); 23 p[rt].rmin = min(p[rt<<1|1].rmin,p[rt<<1|1].sum+p[rt<<1].rmin); 24 } 25 void build(int l,int r,int rt) 26 { 27 int m; 28 if(l == r) 29 { 30 scanf("%d",&p[rt].sum); 31 p[rt].lmax = p[rt].sum; 32 p[rt].rmax = p[rt].sum; 33 p[rt].smax = p[rt].sum; 34 p[rt].lmin = p[rt].sum; 35 p[rt].rmin = p[rt].sum; 36 p[rt].smin = p[rt].sum; 37 return ; 38 } 39 m = (l+r)>>1; 40 build(l,m,rt<<1); 41 build(m+1,r,rt<<1|1); 42 pushup(rt); 43 } 44 void update(int x,int sc,int l,int r,int rt) 45 { 46 int m; 47 if(l == x&&r == x) 48 { 49 p[rt].sum = sc; 50 p[rt].lmax = p[rt].sum; 51 p[rt].rmax = p[rt].sum; 52 p[rt].smax = p[rt].sum; 53 p[rt].lmin = p[rt].sum; 54 p[rt].rmin = p[rt].sum; 55 p[rt].smin = p[rt].sum; 56 return ; 57 } 58 m = (l+r)>>1; 59 if(x <= m) 60 update(x,sc,l,m,rt<<1); 61 if(x > m) 62 update(x,sc,m+1,r,rt<<1|1); 63 pushup(rt); 64 } 65 int main() 66 { 67 int n,m,i,a,b; 68 while(scanf("%d",&n)!=EOF) 69 { 70 build(1,n,1); 71 scanf("%d",&m); 72 for(i = 1;i <= m;i ++) 73 { 74 scanf("%d%d",&a,&b); 75 update(a,b,1,n,1); 76 if(p[1].sum == p[1].smax)//如果总和和最大值相同,断开一个最小值。 77 { 78 printf("%d ",p[1].sum - p[1].smin); 79 } 80 else 81 { 82 printf("%d ",max(p[1].smax,p[1].sum-p[1].smin)); 83 } 84 } 85 } 86 return 0; 87 }