poj 2750 Potted Flower
http://poj.org/problem?id=2750
这道题给出的是个环,如果是一个序列,用线段树很容易做出来,给的是个环就要考虑断点是不是在最大连续和之内。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 2000000 5 using namespace std; 6 7 int n,m,x,y; 8 int a[maxn]; 9 struct node 10 { 11 int l,r; 12 int lmax,rmax,summax; 13 int lmin,rmin,summin; 14 int sum; 15 }tree[maxn*4]; 16 17 18 void up(int i) 19 { 20 tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum; 21 tree[i].lmax=max(tree[i<<1].lmax,tree[i<<1].sum+tree[i<<1|1].lmax); 22 tree[i].rmax=max(tree[i<<1|1].rmax,tree[i<<1|1].sum+tree[i<<1].rmax); 23 tree[i].summax=max(max(tree[i<<1].summax,tree[i<<1|1].summax),tree[i<<1].rmax+tree[i<<1|1].lmax); 24 25 tree[i].lmin=min(tree[i<<1].lmin,tree[i<<1].sum+tree[i<<1|1].lmin); 26 tree[i].rmin=min(tree[i<<1|1].rmin,tree[i<<1|1].sum+tree[i<<1].rmin); 27 tree[i].summin=min(min(tree[i<<1].summin,tree[i<<1|1].summin),tree[i<<1].rmin+tree[i<<1|1].lmin); 28 } 29 void build(int i,int l,int r) 30 { 31 tree[i].l=l; 32 tree[i].r=r; 33 if(l==r) 34 { 35 tree[i].sum=a[l]; 36 tree[i].lmax=tree[i].rmax=tree[i].summax=a[l]; 37 tree[i].lmin=tree[i].rmin=tree[i].summin=a[l]; 38 return ; 39 } 40 int mid=(l+r)>>1; 41 build(i<<1,l,mid); 42 build(i<<1|1,mid+1,r); 43 up(i); 44 } 45 46 void search1(int i,int l,int r,int key) 47 { 48 if(tree[i].l==l&&tree[i].r==r) 49 { 50 tree[i].sum=key; 51 tree[i].lmax=tree[i].rmax=tree[i].summax=key; 52 tree[i].lmin=tree[i].rmin=tree[i].summin=key; 53 return ; 54 } 55 int mid=(tree[i].l+tree[i].r)>>1; 56 if(r<=mid) 57 { 58 search1(i<<1,l,r,key); 59 } 60 else 61 search1(i<<1|1,l,r,key); 62 up(i); 63 } 64 65 66 int main() 67 { 68 while(scanf("%d",&n)!=EOF) 69 { 70 for(int i=1; i<=n; i++) 71 { 72 scanf("%d",&a[i]); 73 } 74 scanf("%d",&m); 75 build(1,1,n); 76 for(int i=0; i<m; i++) 77 { 78 scanf("%d%d",&x,&y); 79 search1(1,x,x,y); 80 if(tree[1].sum==tree[1].summax) 81 { 82 printf("%d\n",tree[1].sum-tree[1].summin); 83 } 84 else 85 printf("%d\n",max(tree[1].summax,tree[1].sum-tree[1].summin)); 86 } 87 } 88 return 0; 89 }