You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations:
modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
Input
The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
The third line contains an integer M. The next M lines contain the operations in following form:
0 x y: modify Ax into y (|y|<=10000).
1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
Output
For each query, print an integer as the problem required.
Example
Input:
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3
Output:
6
4
-3
不知道为什么用我注释掉的update就超时…….
#include<iostream>
#include<stdio.h>
#include<algorithm>
#define MAXN 50020 * 4
using namespace std;
struct Node
{
long left,right;
long lsum,rsum,sum,ans;//左端点连续最大值,rsum以右端点结尾的最大值 sum为区间和 ans 为最终的结果
}tree[MAXN];
long father[MAXN];
int add[MAXN];
void createtree(long rt,long l,long r)
{
tree[rt].left = l;
tree[rt].right = r;
if(l==r)
{
scanf("%d",&tree[rt].ans);
tree[rt].sum = tree[rt].lsum = tree[rt].rsum = tree[rt].ans;
father[l] = rt;
return ;
}
long mid = (l + r)/2;
createtree(rt*2,l,mid);
createtree(rt*2+1,mid + 1,r);
tree[rt].sum = tree[rt*2].sum + tree[rt*2+1].sum;
tree[rt].lsum = tree[rt*2].lsum;
tree[rt].lsum = max(tree[rt].lsum,tree[rt*2].sum + tree[rt*2+1].lsum);
tree[rt].rsum = tree[rt*2+1].rsum;
tree[rt].rsum = max(tree[rt].rsum,tree[rt*2].rsum + tree[rt*2+1].sum);
tree[rt].ans = max(tree[rt*2].rsum + tree[rt*2+1].lsum,max(tree[rt*2].ans,tree[rt*2+1].ans));
}
void update(long rt,long x,long c )//单点更新
{
if(tree[rt].left == tree[rt].right&& tree[rt].left == x)
{
tree[rt].sum = tree[rt].lsum = tree[rt].rsum = tree[rt].ans = c;
return;
}
long mid = (tree[rt].left + tree[rt].right)/2;
if(x<= mid)
update(rt*2,x,c);
else
update(rt*2+1,x,c);
tree[rt].sum = tree[rt*2].sum + tree[rt*2+1].sum;
tree[rt].lsum = tree[rt*2].lsum;
tree[rt].lsum = max(tree[rt].lsum,tree[rt*2].sum + tree[rt*2+1].lsum);
tree[rt].rsum = tree[rt*2+1].rsum;
tree[rt].rsum = max(tree[rt].rsum,tree[rt*2].rsum + tree[rt*2+1].sum);
tree[rt].ans = max(tree[rt*2].rsum + tree[rt*2+1].lsum,max(tree[rt*2].ans,tree[rt*2+1].ans));
/*if(rt==1)
return;
long fr = rt /2;
tree[fr].sum = tree[fr*2].sum + tree[ fr * 2 +1 ].sum;
tree[fr].lsum = max(tree[fr*2].lsum,tree[fr*2+1].lsum + tree[fr*2].sum);
tree[fr].rsum = max(tree[fr*2+1].rsum ,tree[fr*2+1].sum + tree[fr * 2].rsum);
tree[fr].ans = max(tree[fr*2].rsum + tree[fr*2+1].lsum,max(tree[fr*2].ans,tree[fr * 2+1].ans));
update(fr/2);
*/
}
Node query(long rt,long l,long r)
{
if(tree[rt].left == l && tree[rt].right == r)//到达叶子节点
{
return tree[rt];
}
long mid = (tree[rt].left + tree[rt].right)/2;
if(r<= mid)//该区间位于rt的左子树
return query(rt*2,l,r);
else if(l> mid)//右子树
return query(rt*2+1,l,r);
else
{
Node res,lres,rres;
lres = query(rt*2,l,mid);
rres = query(rt*2+1,mid+1,r);
res.sum = lres.sum + rres.sum;
res.lsum = max(lres.lsum,lres.sum + rres.lsum);
res.rsum = max(rres.rsum,rres.sum + lres.rsum);
res.ans = max(rres.lsum + lres.rsum,max(lres.ans,rres.ans));
return res;
}
}
int main()
{
int n,m;
scanf("%d",&n);
createtree(1,1,n);
scanf("%d",&m);
while(m--)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op)
{
Node res = query(1,l,r);
printf("%ld\n",res.ans);
}
else
{
//tree[father[l]].sum = tree[father[l]].ans = tree[father[l]].lsum = tree[father[l] ].rsum = r;
update(1,l,r);
}
}
return 0;
}