1.00s,256MB 输入一个长度n为的数组a,数组下标从1开始计数,数组的元素均为整数且满足-1000<=a[i]<=1000。对该数组可以发m出条指令。指令共有2种:
1 x v,该指令将a[x]的值修改为v; 2 l r,该指令查询区间[l,r]的最大连续子序列和,即区间所有可能的连续子序列中求和的最大值。
本人代码内存超限求调
#include<bits/stdc++.h>
using namespace std;
int oo = 2100000000;
struct node{
int sum,l,r;
int ml,mr,ms;
}tr[800010];
node Trash(node &c){c.sum = c.ml = c.mr = c.ms = -oo;}
inline void pushup(node &c,node &c1,node &c2) {
c.sum = c1.sum + c2.sum;
c.ms = max(max(c1.ms,c2.ms),c1.mr + c2.ml);
c.ml = max(c1.ml,c1.sum + c2.ml);
c.mr = max(c2.mr,c2.sum + c1.mr);
}
inline void build(int l,int r,int c) {
tr[c].l = l,tr[c].r = r;
if(l == r) {
cin >> tr[c].sum;
tr[c].ms = tr[c].ml = tr[c].mr = tr[c].sum;
return;
}
int mid = (l+r)/2;
build(l,mid,c*2);
build(mid+1,r,c*2+1);
pushup(tr[c],tr[c*2],tr[c*2+1]);
}
inline void change(int c,int a,int k) {
if(tr[c].l == tr[c].r) {
tr[c].sum = tr[c].ms = tr[c].ml = tr[c].mr = k;
return;
}
int mid = (tr[c].l + tr[c].r) / 2;
if(a <= mid) change(c*2,a,k);
if(a > mid) change(c*2+1,a,k);
pushup(tr[c],tr[c*2],tr[c*2+1]);
}
inline node query(int c,int ll,int rr) {
node ans,ans1,ans2;
if(tr[c].l < ll || tr[c].r > rr) {Trash(ans);return ans;}
if(tr[c].l >= ll && tr[c].r <= rr) {ans = tr[c];return ans;}
ans1 = query(c*2,ll,rr);
ans2 = query(c*2+1,ll,rr);
pushup(ans,ans1,ans2);
return ans;
}
int main() {
int n, m;
cin >> n >> m;
build(1,n,1);
for(int i = 1; i <= m; i++) {
int x,a,b;
cin >> x >> a >> b;
if(x == 1) change(1,a,b);
if(x == 2) {
node res = query(1,a,b);
cout << res.ms << endl;
}
}
return 0;
}