Little_Joker @ 2023-11-15 17:09:12
还有3天AFO了,调不动了,救救孩子吧[大哭]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=1e6+10;
const ll INF=4557430888798830399;
int n,m;
ll a[maxn],sum[4*maxn],lzy_tag[4*maxn],lzy_tag2[4*maxn],maxx[4*maxn];
//lzy_tag1[]是"加上x"的标记数组; lzy_tag2[]是"修改为x"的标记数组
void build(int l,int r,int p) //p是当前的节点
{
if(l==r){
maxx[p]=a[l];
sum[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,2*p);
build(mid+1,r,2*p+1);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
void push_down_lzy_tag(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]+=lzy_tag[p]*(mid-l+1);
sum[p*2+1]+=lzy_tag[p]*(r-mid);
maxx[p*2]+=lzy_tag[p];
maxx[p*2+1]+=lzy_tag[p];
lzy_tag[p*2]+=lzy_tag[p];
lzy_tag[p*2+1]+=lzy_tag[p];
lzy_tag[p]=0;
}
void push_down_lzy_tag2(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]=lzy_tag2[p]*(mid-l+1);
sum[p*2+1]=lzy_tag2[p]*(r-mid);
maxx[p*2]=lzy_tag2[p];
maxx[p*2+1]=lzy_tag2[p];
lzy_tag2[p*2]=lzy_tag2[p];
lzy_tag2[p*2+1]=lzy_tag2[p];
lzy_tag2[p]=0;
}
ll getmax(int l,int r,int L,int R,int p) //[L,R]是要查询的区间
{
if(L<=l&&r<=R) return maxx[p];
int mid=(l+r)>>1;
ll maxxx=-INF;
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
if(L<=mid) maxxx=max(maxxx,getmax(l,mid,L,R,p*2));
if(R>mid) maxxx=max(maxxx,getmax(mid+1,r,L,R,p*2+1));
return maxxx;
}
void update(int l,int r,int L,int R,int p,int f)
{
if(L<=l&&r<=R)
{
sum[p]+=(r-l+1)*f;
maxx[p]+=f;
lzy_tag[p]+=f;
return;
}
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,L,R,p*2,f);
if(R>mid) update(mid+1,r,L,R,p*2+1,f);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
void update2(int l,int r,int L,int R,int p,int f)
{
if(L<=l&&r<=R){
sum[p]=(r-l+1)*f;
maxx[p]=f;
lzy_tag2[p]=f;
return;
}
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
int mid=(l+r)>>1;
if(L<=mid) update2(l,mid,L,R,p*2,f);
if(R>mid) update2(mid+1,r,L,R,p*2+1,f);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
int main()
{
scanf("%d%d",&n,&m);
memset(maxx,-0x3f,sizeof(maxx));
memset(lzy_tag2,0x3f,sizeof(lzy_tag2));
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
int k;
scanf("%d",&k);
update2(1,n,x,y,1,k);
}
else if(op==2){
int k;
scanf("%d",&k);
update(1,n,x,y,1,k);
}
else if(op==3){
printf("%lld\n",getmax(1,n,x,y,1));
}
}
return 0;
}
WA on #7~10
by qnqfff @ 2023-11-15 17:21:55
@Little_Joker
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=1e6+10;
const ll INF=4557430888798830399;
int n,m;
ll a[maxn],sum[4*maxn],lzy_tag[4*maxn],lzy_tag2[4*maxn],maxx[4*maxn];
//lzy_tag1[]是"加上x"的标记数组; lzy_tag2[]是"修改为x"的标记数组
void build(int l,int r,int p) //p是当前的节点
{
if(l==r){
maxx[p]=a[l];
sum[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,2*p);
build(mid+1,r,2*p+1);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
void push_down_lzy_tag(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]+=lzy_tag[p]*(mid-l+1);
sum[p*2+1]+=lzy_tag[p]*(r-mid);
maxx[p*2]+=lzy_tag[p];
maxx[p*2+1]+=lzy_tag[p];
lzy_tag[p*2]+=lzy_tag[p];
lzy_tag[p*2+1]+=lzy_tag[p];
lzy_tag[p]=0;
}
void push_down_lzy_tag2(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]=lzy_tag2[p]*(mid-l+1);
sum[p*2+1]=lzy_tag2[p]*(r-mid);
maxx[p*2]=lzy_tag2[p];
maxx[p*2+1]=lzy_tag2[p];
lzy_tag2[p*2]=lzy_tag2[p];
lzy_tag2[p*2+1]=lzy_tag2[p];
lzy_tag2[p]=INF;
lzy_tag[p*2]=lzy_tag[p*2+1]=0;
}
ll getmax(int l,int r,int L,int R,int p) //[L,R]是要查询的区间
{
if(L<=l&&r<=R) return maxx[p];
int mid=(l+r)>>1;
ll maxxx=-INF;
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
if(L<=mid) maxxx=max(maxxx,getmax(l,mid,L,R,p*2));
if(R>mid) maxxx=max(maxxx,getmax(mid+1,r,L,R,p*2+1));
return maxxx;
}
void update(int l,int r,int L,int R,int p,int f)
{
if(L<=l&&r<=R)
{
sum[p]+=(r-l+1)*f;
maxx[p]+=f;
lzy_tag[p]+=f;
return;
}
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,L,R,p*2,f);
if(R>mid) update(mid+1,r,L,R,p*2+1,f);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
void update2(int l,int r,int L,int R,int p,int f)
{
if(L<=l&&r<=R){
sum[p]=(r-l+1)*f;
maxx[p]=f;
lzy_tag2[p]=f;
lzy_tag[p]=0;
return;
}
if(lzy_tag2[p]!=INF)
{
push_down_lzy_tag2(l,r,p);
}
if(lzy_tag[p])
{
push_down_lzy_tag(l,r,p);
}
int mid=(l+r)>>1;
if(L<=mid) update2(l,mid,L,R,p*2,f);
if(R>mid) update2(mid+1,r,L,R,p*2+1,f);
sum[p]=sum[p*2]+sum[p*2+1];
maxx[p]=max(maxx[2*p],maxx[2*p+1]);
}
int main()
{
scanf("%d%d",&n,&m);
memset(maxx,-0x3f,sizeof(maxx));
memset(lzy_tag2,0x3f,sizeof(lzy_tag2));
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
int k;
scanf("%d",&k);
update2(1,n,x,y,1,k);
}
else if(op==2){
int k;
scanf("%d",&k);
update(1,n,x,y,1,k);
}
else if(op==3){
printf("%lld\n",getmax(1,n,x,y,1));
}
}
return 0;
}
by Exp10re @ 2023-11-15 17:29:04
@Little_Joker
update2 里面的:
if(L<=l&&r<=R){
sum[p]=(r-l+1)*f;
maxx[p]=f;
lzy_tag2[p]=f;
return;
}
改为:
if(L<=l&&r<=R){
sum[p]=(r-l+1)*f;
maxx[p]=f;
lzy_tag2[p]=f;
lzy_tag[p]=0;
return;
}
push_down_lzy_tag2 后面
void push_down_lzy_tag2(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]=lzy_tag2[p]*(mid-l+1);
sum[p*2+1]=lzy_tag2[p]*(r-mid);
maxx[p*2]=lzy_tag2[p];
maxx[p*2+1]=lzy_tag2[p];
lzy_tag2[p*2]=lzy_tag2[p];
lzy_tag2[p*2+1]=lzy_tag2[p];
lzy_tag2[p]=0;//here
}
void push_down_lzy_tag2(int l,int r,int p)
{
int mid=(l+r)>>1;
sum[p*2]=lzy_tag2[p]*(mid-l+1);
sum[p*2+1]=lzy_tag2[p]*(r-mid);
maxx[p*2]=lzy_tag2[p];
maxx[p*2+1]=lzy_tag2[p];
lzy_tag2[p*2]=lzy_tag2[p];
lzy_tag2[p*2+1]=lzy_tag2[p];
lzy_tag2[p]=INF;//here
lzy_tag[p*2+1]=0;
lzy_tag[p*2]=0;
}
by Exp10re @ 2023-11-15 17:30:00
@Little_Joker 原理是区间覆盖优先级大于区间加。
by Little_Joker @ 2023-11-15 17:37:32
@Exp10re @qnqfff 跪谢大佬终于AC了