5t0_0r2 @ 2023-08-30 16:24:11
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 9,ROOT = 1,INF = 1e9 + 9;
int a[N];
struct seg_tree{
struct node {
int val,sum,lsum,rsum,change;
} tree[N << 2];
bool in_range(int l,int r,int now_l,int now_r){
return l <= now_l && now_r <= r;
}
bool out_range(int l,int r,int now_l,int now_r){
return now_r < l || now_l > r;
}
int len(int l,int r){
return r - l + 1;
}
void push_up(int root){
int lchild = root * 2,rchild = root * 2 + 1;
tree[root].sum = tree[lchild].sum + tree[rchild].sum;
tree[root].val = max(max(tree[lchild].val,tree[rchild].val),tree[lchild].rsum + tree[rchild].lsum);
tree[root].lsum = max(tree[lchild].lsum,tree[lchild].sum + tree[rchild].lsum);
tree[root].rsum = max(tree[rchild].rsum,tree[rchild].sum + tree[lchild].rsum);
}
void make_tag(int Len,int root,int change){
tree[root].change = change;
tree[root].val = tree[root].sum = tree[root].lsum = tree[root].rsum = Len * change;
}
void push_down(int l,int r,int root){
int mid = (l + r) / 2,lchild = root * 2,rchild = root * 2 + 1;
if(tree[root].change != INF){
make_tag(len(l,mid),lchild,tree[root].change);
make_tag(len(mid + 1,r),rchild,tree[root].change);
tree[root].change = INF;
}
}
void build(int l,int r,int root) {
tree[root].change = INF;
if(l == r) {
tree[root].val = tree[root].sum = tree[root].lsum = tree[root].rsum = a[l];
return;
}
int mid = (l + r) / 2,lchild = root * 2,rchild = root * 2 + 1;
build(l,mid,lchild);
build(mid + 1,r,rchild);
push_up(root);
}
void update(int l,int r,int now_l,int now_r,int root,int change) {
if(in_range(l,r,now_l,now_r))
make_tag(len(l,r),root,change);
else if(!out_range(l,r,now_l,now_r)){
int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
push_down(now_l,now_r,root);
update(l,r,mid + 1,now_r,rchild,change);
update(l,r,now_l,mid,lchild,change);
push_up(root);
}
return;
}
int getsum(int l, int r, int now_l, int now_r, int root) {
int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
if(in_range(l,r,now_l,now_r))
return tree[root].val;
else if(!out_range(l,r,now_l,now_r)){
push_down(now_l,now_r,root);
return max(getsum(l,r,now_l,mid,lchild),getsum(l,r,mid + 1,now_r,rchild));
}
else
return -INF;
}
} seg;
int n,m;
int op,x,y,k;
signed main() {
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
seg.build(1,n,ROOT);
for(int i = 1; i <= m; i++) {
scanf("%lld%lld%lld", &op, &x, &y);
if(op == 1){
if(x > y)
swap(x,y);
printf("%lld\n",seg.getsum(x,y,1,n,ROOT));
}
else
seg.update(x,x,1,n,ROOT,y);
}
}
by 5t0_0r2 @ 2023-08-30 16:24:37
打错了,N 是 5e5 + 9
by Michaellg @ 2023-08-30 16:34:39
@5t0_0r2 getsum 的合并要和 pushup 一样,不能直接取 max,要将 getsum 返回值变成 node。
return Node {
max(max(L.ms, R.ms), L.rms + R.lms),
L.s + R.s,
max(L.lms, L.s + R.lms),
max(R.rms, R.s + L.rms)
};
by 5t0_0r2 @ 2023-08-30 16:38:34
@Michaellg 能结合我的代码告诉我吗(好多变量我都没看懂什么意思)
by Michaellg @ 2023-08-30 16:41:44
@5t0_0r2 ms,s,lms,rms 分别对应 val,sum,lsum,rsum
by 5t0_0r2 @ 2023-08-30 16:44:29
@Michaellg 那 L 和 R 呢?左右子节点?
by Michaellg @ 2023-08-30 16:45:06
@5t0_0r2 还要注意线段树 getsum 时如果子节点被递归了两次,复杂度会炸掉,所以要把子节点递归结果先记录下来
by Michaellg @ 2023-08-30 16:45:44
L 和 R 就是子节点的结果
by 5t0_0r2 @ 2023-08-30 17:01:27
@Michaellg
node getsum(int l, int r, int now_l, int now_r, int root) {
int mid = (now_l + now_r) / 2,lchild = root * 2,rchild = root * 2 + 1;
if(in_range(l,r,now_l,now_r))
return tree[root];
else if(!out_range(l,r,now_l,now_r)){
push_down(now_l,now_r,root);
node L = getsum(l,r,now_l,mid,lchild),R = getsum(l,r,mid + 1,now_r,rchild);
return
(node){
L.sum + R.sum,
max(max(L.val,R.val),L.rsum + R.lsum),
max(L.lsum,L.sum + R.lsum),
max(R.rsum,R.sum + L.rsum),
tree[root].change
};
}
}
这样吗?现在爆零了
by Michaellg @ 2023-08-30 17:05:30
@5t0_0r2 L.sum + R.sum 和 max(max(L.val,R.val),L.rsum + R.lsum 写反了
by 5t0_0r2 @ 2023-08-30 17:09:10
@Michaellg 还是爆零