社区讨论
简单区间最大和,求救!!!
学术版参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @m3bm7vyp
- 此快照首次捕获于
- 2024/11/10 21:13 去年
- 此快照最后确认于
- 2025/11/04 14:56 4 个月前
P6792 [SNOI2020] 区间和调了很久还是95分,而且错的那个点是第48个输出。代码写的是有点史的,f[1][1]代表左右端点都取时的最大,别的以此类推。然后懒标记的处理是有问题的,因为好像区间修改时有负数,所以懒标记为0有时也有意义,但我处理过却仍未完全通过,代码如下
CPP#include<iostream>
#include<cstdio>
#include<cmath>
#define lp p*2
#define rp p*2+1
#define N 200010
#define int long long
using namespace std;
int n, q, a[N];
struct node{
int l, r, tag, vistag;
int minn, maxn;
int f[2][2];
}tree[N<<2];
void push_up(int p){
tree[p].l = tree[lp].l;
tree[p].r = tree[rp].r;
tree[p].f[0][0] = max(max(max(tree[lp].f[0][0], tree[lp].f[0][1]), max(tree[lp].f[0][1]+tree[rp].f[1][0], tree[rp].f[0][0])), tree[rp].f[1][0]);
tree[p].f[0][1] = max(max(tree[lp].f[0][1]+tree[rp].f[1][1], tree[rp].f[0][1]), tree[rp].f[1][1]);
tree[p].f[1][0] = max(max(tree[lp].f[1][1]+tree[rp].f[1][0], tree[lp].f[1][0]), tree[lp].f[1][1]);
tree[p].f[1][1] = tree[lp].f[1][1]+tree[rp].f[1][1];
tree[p].minn = min(tree[lp].minn, tree[rp].minn);
tree[p].maxn = max(tree[lp].maxn, tree[rp].maxn);
}
void build(int p, int l, int r){
if(l == r){
tree[p].l = l;
tree[p].r = r;
tree[p].vistag = 0;
tree[p].minn = tree[p].maxn = a[l];
tree[p].f[1][1] = a[l];
return ;
}
int mid = (l+r)>>1;
build(lp, l, mid);
build(rp, mid+1, r);
push_up(p);
}
void addtag(int p, int x){
int num = tree[p].r-tree[p].l+1;
tree[p].tag = x;
tree[p].vistag = 1;
tree[p].minn = tree[p].maxn = x;
tree[p].f[0][0] = max((num-2)*x, x);
tree[p].f[0][1] = max((num-1)*x, x);
tree[p].f[1][0] = max((num-1)*x, x);
tree[p].f[1][1] = num*x;
}
void push_down(int p){
addtag(lp, tree[p].tag);
addtag(rp, tree[p].tag);
tree[p].tag = 0;
tree[p].vistag = 0;
}
void update(int p, int l, int r, int x){
if(tree[p].minn >= x) return ;
if(tree[p].vistag) push_down(p);
if(tree[p].l == tree[p].r){
tree[p].f[1][1] = max(tree[p].f[1][1], x);
tree[p].minn = tree[p].maxn = tree[p].f[1][1];
return ;
}
if(tree[p].l>=l && tree[p].r<=r && tree[p].maxn<=x){
addtag(p, x);
return ;
}
int mid = (tree[p].l+tree[p].r)>>1;
if(l<=mid) update(lp, l, r, x);
if(r>mid) update(rp, l, r, x);
push_up(p);
}
node query(int p, int l, int r){
node tmpl, tmpr, tmp;
for(int i=0; i<=1; i++)
for(int j=0; j<=1; j++){
tmpl.f[i][j] = 0;
tmpr.f[i][j] = 0;
tmp.f[i][j] = 0;
}
if(tree[p].l>=l && tree[p].r<=r) return tree[p];
if(tree[p].vistag) push_down(p);
int mid = (tree[p].l+tree[p].r)>>1;
if(l<=mid) tmpl = query(lp, l, r);
if(r>mid) tmpr = query(rp, l, r);
tmp.f[0][0] = max(max(max(tmpl.f[0][0], tmpl.f[0][1]), max(tmpl.f[0][1]+tmpr.f[1][0], tmpr.f[0][0])), tmpr.f[1][0]);
tmp.f[0][1] = max(max(tmpl.f[0][1]+tmpr.f[1][1], tmpr.f[0][1]), tmpr.f[1][1]);
tmp.f[1][0] = max(max(tmpl.f[1][1]+tmpr.f[1][0], tmpl.f[1][0]), tmpl.f[1][1]);
tmp.f[1][1] = tmpl.f[1][1]+tmpr.f[1][1];
tmp.minn = min(tmpl.minn, tmpr.minn);
tmp.maxn = max(tmpl.maxn, tmpr.maxn);
//cout << tmp.f[1][1] << endl;
return tmp;
}
signed main()
{
//freopen("P6792.in","r",stdin);
//freopen("P6792.out","w",stdout);
scanf("%lld%lld", &n, &q);
for(int i=1; i<=n; i++)
cin >> a[i];
build(1, 1, n);
//for(int i=1; i<=400; i++)
//cout<<tree[i].f[1][1] << endl;
while(q--){
int c, l, r, x;
scanf("%lld", &c);
if(c == 0){
scanf("%lld%lld%lld", &l, &r, &x);
update(1, l, r, x);
}
if(c == 1){
scanf("%lld%lld", &l, &r);
node ans = query(1, l, r);
printf("%lld\n", max(max(ans.f[0][0], ans.f[1][1]), max(ans.f[1][0], ans.f[0][1])));
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...