poj2750

来源:互联网 发布:赚钱的行业知乎 编辑:程序博客网 时间:2024/05/19 02:30

Potted Flower
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 4843 Accepted: 1846

Description

The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrounded by N pots of flowers. Each potted flower will be assigned to an integer number (possibly negative) denoting how attractive it is. See the following graph as an example: 

(Positions of potted flowers are assigned to index numbers in the range of 1 ... N. The i-th pot and the (i + 1)-th pot are consecutive for any given i (1 <= i < N), and 1st pot is next to N-th pot in addition.) 



The board chairman informed the little cat to construct "ONE arc-style cane-chair" for tourists having a rest, and the sum of attractive values of the flowers beside the cane-chair should be as large as possible. You should notice that a cane-chair cannot be a total circle, so the number of flowers beside the cane-chair may be 1, 2, ..., N - 1, but cannot be N. In the above example, if we construct a cane-chair in the position of that red-dashed-arc, we will have the sum of 3+(-2)+1+2=4, which is the largest among all possible constructions. 

Unluckily, some booted cats always make trouble for the little cat, by changing some potted flowers to others. The intelligence agency of little cat has caught up all the M instruments of booted cats' action. Each instrument is in the form of "A B", which means changing the A-th potted flowered with a new one whose attractive value equals to B. You have to report the new "maximal sum" after each instruction. 

Input

There will be a single test data in the input. You are given an integer N (4 <= N <= 100000) in the first input line. 

The second line contains N integers, which are the initial attractive value of each potted flower. The i-th number is for the potted flower on the i-th position. 

A single integer M (4 <= M <= 100000) in the third input line, and the following M lines each contains an instruction "A B" in the form described above. 

Restriction: All the attractive values are within [-1000, 1000]. We guarantee the maximal sum will be always a positive integer. 

Output

For each instruction, output a single line with the maximum sum of attractive values for the optimum cane-chair.

Sample Input

53 -2 1 2 -542 -25 -52 -45 -1

Sample Output

4435

题意:在环上找到一个连续的子序列,使得和最大。

题解:因为是单点更新,所以要和线段树挂钩起来,关键是线段树维护的内容有点多。

分别是1、区间的和;2、区间的最大,最小值;3、区间从左边开始连续序列的最大,最小值;4、区间从右边开始连续序列的最大,最小值;5、区间连续子序列的最大最小值。

前两个比较简单,第三个就在该区间左子区间从左边开始连续序列的最大和左子区间加上右子区间从左边开始连续序列的最大中取最大值(最小值同理)。第四和第三一样的。

第五就是在三个区间中找最大最小。分别是:1、左子区间的最大连续子序列和。2、右子区间的最大连续子序列和。3、左子区间从右边开始连续子序列的最大和与右子区间从左边开始连续子序列的最大和(最小也是一样的)。

最后输出答案时:

1、如果所有数都小于等于0,输出最大值。

2、如果所有数都大于等于0,输出总和减最小值。

3、如果总区间最大连续子序列和比总和减去最小连续子列的和小,那么输出总和减去最小连续子列的和。

代码:

//Wud#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <sstream>#include <fstream>#include <set>#include <map>#include <string.h>#define EPS 1e-9#define M_PI 3.14159265358979323846using namespace std;typedef pair<int,int> P;typedef long long ll;const int maxn = 1e5+7;int d[maxn];int n;struct node {    int l,r;    int sum,m,mi,lm,lmi,rm,rmi,mm,mmi;} s[4*maxn];void push_up(int x){    s[x].sum = s[x<<1].sum+s[x<<1|1].sum;    s[x].m = max(s[x<<1].m,s[x<<1|1].m);    s[x].mi = min(s[x<<1].mi,s[x<<1|1].mi);    s[x].lm = max(s[x<<1].lm,s[x<<1|1].lm+s[x<<1].sum);    s[x].lmi = min(s[x<<1].lmi,s[x<<1|1].lmi+s[x<<1].sum);    s[x].rm = max(s[x<<1|1].rm,s[x<<1].rm+s[x<<1|1].sum);    s[x].rmi = min(s[x<<1|1].rmi,s[x<<1].rmi+s[x<<1|1].sum);    s[x].mm = max(max(s[x<<1].mm,s[x<<1|1].mm),s[x<<1|1].lm+s[x<<1].rm);    s[x].mmi = min(min(s[x<<1].mmi,s[x<<1|1].mmi),s[x<<1|1].lmi+s[x<<1].rmi);}void build(int x,int l,int r){    s[x].l = l,s[x].r = r;    s[x].sum = s[x].mmi = s[x].mm = s[x].lm = s[x].lmi = s[x].rmi = s[x].rm = s[x].m = s[x].mi = 0;    if(l == r)    {        s[x].sum = s[x].mmi = s[x].mm = s[x].lm = s[x].lmi = s[x].rmi = s[x].rm = s[x].m = s[x].mi = d[l];    }    else{        int mid = (l+r)/2;        build(x<<1,l,mid);        build(x<<1|1,mid+1,r);        push_up(x);    }}void update(int x,int a,int b){    int L = s[x].l,R = s[x].r;    int mid = (L+R)/2;    if(L==R) s[x].sum = s[x].mmi = s[x].mm = s[x].lm = s[x].lmi = s[x].rmi = s[x].rm = s[x].m = s[x].mi = b;    else if(a<=mid){        update(x<<1,a,b);        push_up(x);    }    else {        update(x<<1|1,a,b);        push_up(x);    }}int main(void){    while (scanf("%d",&n)!=EOF){        for (int i = 1;i <= n;i++){            scanf("%d",&d[i]);        }        build(1,1,n);        int t;        scanf("%d",&t);        while(t--){            int a,b;            scanf("%d %d",&a,&b);            update(1,a,b);            if(s[1].mm<s[1].sum-s[1].mmi)                s[1].mm = s[1].sum-s[1].mmi;            if(s[1].mi>=0)                printf("%d\n",s[1].sum-s[1].mi);            else if(s[1].m<=0)                printf("%d\n",s[1].m);            else if(s[1].mm<s[1].sum-s[1].mmi){                printf("%d\n",s[1].sum-s[1].mmi);            }            else printf("%d\n",s[1].mm);        }    }    return 0;}



1 0