const int maxn = 50100;
struct node{
int l,r;
int maxl,maxr,maxs; //左子区间,右子区间,总区间最大子段和
int sum; //区间总和
}tree[maxn<<2];
int num[maxn];
void update(node &now,node <,node &rt)
{
now.sum = lt.sum + rt.sum;
now.maxl = max(lt.maxl,lt.sum+rt.maxl);
now.maxr = max(rt.maxr,rt.sum+lt.maxr);
now.maxs = max(lt.maxs,rt.maxs);
now.maxs = max(now.maxs,lt.maxr+rt.maxl);
return ;
}
void build(int k,int l,int r)
{
tree[k].l = l,tree[k].r = r;
if(l == r){
tree[k].maxs = num[l];
tree[k].maxl = num[l];
tree[k].maxr = num[l];
tree[k].sum = num[l];
return ;
}
int mid = (l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(tree[k],tree[k*2],tree[k*2+1]);
return ;
}
void change(int k,int x,int y)
{
if(tree[k].l == x && tree[k].r == x){
tree[k].maxs = y;
tree[k].sum = y;
tree[k].maxl = y;
tree[k].maxr = y;
return ;
}
int mid = (tree[k].l + tree[k].r)>>1;
if(x<=mid)
change(k<<1,x,y);
else
change(k<<1|1,x,y);
update(tree[k],tree[k<<1],tree[k<<1|1]);
return ;
}
node query(int k,int l,int r)
{
if(tree[k].l>=l&&tree[k].r<=r){
return tree[k];
}
int mid = (tree[k].l+tree[k].r)>>1;
if(r <= mid) //这里注意,当查询区在左子区间时,直接查询左子区间
return query(k<<1,l,r);
else if(l > mid) //这里注意,当查询区在右子区间时,直接查询右子区间
return query(k<<1|1,l,r);
else{ //左右都有就………
node left,right,result;
left = query(k<<1,l,mid);
right = query(k<<1|1,mid+1,r);
update(result,left,right);
return result;
}
}
模板题:Can you answer these queries III
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
注意结果超出 int 范围
AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<ctype.h>
#include<vector>
#include<algorithm>
#include<sstream>
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 50100;
struct node{
ll l,r;
ll maxl,maxr,maxs;
ll sum;
}tree[maxn<<2];
ll num[maxn];
void update(node &now,node <,node &rt)
{
now.sum = lt.sum + rt.sum;
now.maxl = max(lt.maxl,lt.sum+rt.maxl);
now.maxr = max(rt.maxr,rt.sum+lt.maxr);
now.maxs = max(lt.maxs,rt.maxs);
now.maxs = max(now.maxs,lt.maxr+rt.maxl);
return ;
}
void build(int k,ll l,ll r)
{
tree[k].l = l,tree[k].r = r;
if(l == r){
tree[k].maxs = num[l];
tree[k].maxl = num[l];
tree[k].maxr = num[l];
tree[k].sum = num[l];
return ;
}
ll mid = (l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(tree[k],tree[k*2],tree[k*2+1]);
return ;
}
void change(int k,ll x,ll y)
{
if(tree[k].l == x && tree[k].r == x){
tree[k].maxs = y;
tree[k].sum = y;
tree[k].maxl = y;
tree[k].maxr = y;
return ;
}
ll mid = (tree[k].l + tree[k].r)>>1;
if(x<=mid)
change(k<<1,x,y);
else
change(k<<1|1,x,y);
update(tree[k],tree[k<<1],tree[k<<1|1]);
return ;
}
node query(ll k,ll l,ll r)
{
if(tree[k].l>=l&&tree[k].r<=r){
return tree[k];
}
ll mid = (tree[k].l+tree[k].r)>>1;
if(r <= mid)
return query(k<<1,l,r);
else if(l > mid)
return query(k<<1|1,l,r);
else{
node left,right,result;
left = query(k<<1,l,mid);
right = query(k<<1|1,mid+1,r);
update(result,left,right);
return result;
}
}
int main(void)
{
int n,m;
int a;
ll b,c;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",num+i);
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%lld%lld",&a,&b,&c);
if(a==0) change(1,b,c);
if(a==1){
printf("%lld\n",query(1,b,c).maxs);
}
}
return 0;
}