题目描述
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.
Sample Input
5
3 -2 1 2 -5
4
2 -2
5 -5
2 -4
5 -1
Sample Output
4
4
3
5
4 ≤ N ≤ 1 0 5 , 4 ≤ M ≤ 1 0 5 4\leq N \leq 10^5,4\leq M\leq 10^5 4≤N≤105,4≤M≤105
题解
前置知识:线段树优化DP
题目大意就是给一个首尾相邻的环形数组和
M
M
M条指令,每条指令会修改环形数组上的一个数。对于每条指令,输出执行指令后的最大子段和,最大字段和不能包含所有元素。
首先,破环为链,将环形数组变成一个长度为 n n n的序列。把序列放在线段树上,维护各区间的最大子段和 m x mx mx和最小子段和 m n mn mn。
分三种情况:
1.最大子段和为 [ l , r ] [l,r] [l,r], l < r l<r l<r,则答案为 m x mx mx
2.最大子段和跨越环形数组的尾部绕到了头部,则答案为 s u m − m n sum-mn sum−mn
3.若最大子段和= s u m sum sum,则答案为 s u m − m n sum-mn sum−mn
总时间复杂度为 O ( M l o g N ) O(MlogN) O(MlogN)
code
#include<iostream>
#include<cstdio>
#define lc k<<1
#define rc k<<1|1
using namespace std;
int n,m,x,y,sum,ans,a[100005],v[400005];
struct node{
int lx,rx,x;
}mx[400005],mn[400005];
int max(int ax,int bx){
return ax>bx?ax:bx;
}
int min(int ax,int bx){
return ax<bx?ax:bx;
}
void build(int k,int l,int r){
if(l==r){
mx[k].lx=mx[k].rx=mx[k].x=a[l];
mn[k].lx=mn[k].rx=mn[k].x=a[l];
v[k]=a[l];
return;
}
int mid=(l+r)/2;
build(lc,l,mid);
build(rc,mid+1,r);
v[k]=v[lc]+v[rc];
mx[k].lx=max(mx[lc].lx,v[lc]+mx[rc].lx);
mn[k].lx=min(mn[lc].lx,v[lc]+mn[rc].lx);
mx[k].rx=max(mx[rc].rx,v[rc]+mx[lc].rx);
mn[k].rx=min(mn[rc].rx,v[rc]+mn[lc].rx);
mx[k].x=max(max(mx[lc].x,mx[rc].x),mx[lc].rx+mx[rc].lx);
mn[k].x=min(min(mn[lc].x,mn[rc].x),mn[lc].rx+mn[rc].lx);
}
void ch(int k,int l,int r,int x,int y){
if(l==r&&l==x){
mx[k].lx=mx[k].rx=mx[k].x=y;
mn[k].lx=mn[k].rx=mn[k].x=y;
v[k]=y;
return;
}
if(l>x||r<x) return;
if(l==r) return;
int mid=(l+r)/2;
if(x<=mid) ch(lc,l,mid,x,y);
else ch(rc,mid+1,r,x,y);
v[k]=v[lc]+v[rc];
mx[k].lx=max(mx[lc].lx,v[lc]+mx[rc].lx);
mn[k].lx=min(mn[lc].lx,v[lc]+mn[rc].lx);
mx[k].rx=max(mx[rc].rx,v[rc]+mx[lc].rx);
mn[k].rx=min(mn[rc].rx,v[rc]+mn[lc].rx);
mx[k].x=max(max(mx[lc].x,mx[rc].x),mx[lc].rx+mx[rc].lx);
mn[k].x=min(min(mn[lc].x,mn[rc].x),mn[lc].rx+mn[rc].lx);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
ch(1,1,n,x,y);
sum=sum-a[x]+y;
a[x]=y;
ans=mx[1].x;
if(ans==sum) ans=sum-mn[1].x;
else ans=max(ans,sum-mn[1].x);
printf("%d\n",ans);
}
return 0;
}