NirvanaCeleste @ 2024-11-22 22:06:48
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500100;
void read(int &x){
int y=0,w=1;
char ch=getchar();
while(ch < '0' || ch > '9'){if(ch=='-')w=-1;ch=getchar();}
while(ch >= '0' && ch <= '9'){y=y*10+ch-'0';ch=getchar();}
x=y*w;
}
void write(int x){
if(x < 0) x=-x,putchar('-');
if(x > 9) write(x/10);
putchar(x%10+'0');
}
int n,m;
int a[maxn];
struct node{
int sum,ans,maxl,maxr;
}t[maxn*4];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
inline void pushup(int p){
t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
t[p].maxl = max(t[ls(p)].maxl,t[ls(p)].sum + t[rs(p)].maxl);
t[p].maxr = max(t[rs(p)].maxr,t[rs(p)].sum + t[ls(p)].maxr);
t[p].ans = max(t[ls(p)].maxl,t[rs(p)].maxr);
t[p].ans = max(t[p].ans,t[ls(p)].maxr + t[rs(p)].maxl);
t[p].ans = max(t[p].ans,t[ls(p)].sum + t[rs(p)].maxl);
t[p].ans = max(t[p].ans,t[rs(p)].sum + t[ls(p)].maxr);
t[p].ans = max(t[p].ans,t[ls(p)].ans);//
t[p].ans = max(t[p].ans,t[rs(p)].ans);//
}
inline void nodeadd(int p,int k){
t[p].sum += k;
t[p].maxl += k;
t[p].maxr += k;
t[p].ans += k;
}
void build(int p,int l,int r){
if(l == r){
nodeadd(p,a[l]);
return;
}
int mid = (l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
int ask(int p,int l,int r,int nl,int nr){
int res = INT_MIN;
if(nl <= l && r <= nr || l == r) return t[p].ans;
int mid = (l + r) >> 1;
if(mid < nr) res = max(res,ask(rs(p),mid+1,r,nl,nr));
if(mid >= nl) res = max(res,ask(ls(p),l,mid,nl,nr));
return res;
}
void add(int p,int l,int r,int x,int k){
if(l == r){
nodeadd(p,k);
return;
}
int mid = (l + r) >> 1;
if(mid < x) add(rs(p),mid+1,r,x,k);
if(mid >= x) add(ls(p),l,mid,x,k);
pushup(p);
}
int main(){
read(n),read(m);
for(int i=1;i<=n;i++) read(a[i]);
build(1,1,n);
int k,x,y;
while(m--){
read(k),read(x),read(y);
if(k == 1){
if(x > y) swap(x,y);
write(ask(1,1,n,x,y)),putchar('\n');
}
if(k == 2) add(1,1,n,x,y-a[x]),a[x]=y;
}
return 0;
}
by chenxi2009 @ 2024-11-23 09:55:58
@NirvanaCeleste 单点 maxl maxr 不是这个点的值,应该是这个点和 0 取 max。
by chenxi2009 @ 2024-11-23 09:59:03
sry,搞错了。
by chenxi2009 @ 2024-11-23 10:08:14
@NirvanaCeleste 询问时的答案返回不对,有可能既不是左边、右边区间的最大值,还有可能是左右两边各取一点。建议询问操作改成结构体类型。
by NirvanaCeleste @ 2024-11-23 10:13:45
@chenxi2009 一段区间的最大连续子段和是不是可能来自以下五种情况:
1. |++++++------|-----------|
2. |------------|------+++++|
3. |++++++++++++|++++-------|
4. |--------++++|+++++++++++|
5. |--------++++|++++-------|
by NirvanaCeleste @ 2024-11-23 10:14:33
@chenxi2009 第五种情况是不是左右两边各取一点的情况
by NirvanaCeleste @ 2024-11-23 10:15:49
pushup中第五行
t[p].ans = max(t[p].ans,t[ls(p)].maxr + t[rs(p)].maxl);
是否对应这种情况
by chenxi2009 @ 2024-11-23 10:16:27
@NirvanaCeleste 对,询问时可能取了很多个区间(如
by chenxi2009 @ 2024-11-23 10:17:21
@NirvanaCeleste 对的。建议写一个结构体区间合并函数,同时代替 pushup 和询问合并。
by NirvanaCeleste @ 2024-11-23 10:17:47
sry 我明白了 pushup没写错 是不是ask写错了
by NirvanaCeleste @ 2024-11-23 10:24:28
@chenxi2009 可以这样理解 ask中只考虑了左右两个区间分开的答案 如
|---+++++---|--++++++---|
但是没有考虑 两端小区间可以合并的情况
|------+++|+++++---|
这种只会返回左右两者的较大值
感谢 以关 qwq