社区讨论

简单区间最大和,求救!!!

学术版参与者 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 条回复,欢迎继续交流。

正在加载回复...