Rt
cov 表示是否被摊平
tag1 是摊平成的数
tag2 是摊平后加的数
tag3 是摊平前最大的加数
tag4 是摊平后最大的(摊平数+加数)
测试点 7,8 已过,应该是区间摊平出问题了。
代码写得可能有点乱,但还是请大佬将就看一下,已经调了半天了。
应该没有人会看完整代码吧,就只发可能错的代码了。
修改代码:
void update_add(int ql,int qr,int k,int p)
{
if(ql>s[p].r||qr<s[p].l)return;
if(ql<=s[p].l&&s[p].r<=qr)
{
s[p].maxa+=k;
s[p].maxb=max(s[p].maxb,s[p].maxa);
s[p].tag2+=k;
if(!s[p].cov)s[p].tag3=max(s[p].tag3,s[p].tag2);
else s[p].tag4=max(s[p].tag4,s[p].tag1+s[p].tag2);
return;
}
push_down(p);
update_add(ql,qr,k,p*2),update_add(ql,qr,k,p*2+1);
push_up(p);
}
void update_cov(int ql,int qr,int k,int p)
{
if(ql>s[p].r||qr<s[p].l)return;
if(ql<=s[p].l&&s[p].r<=qr)
{
s[p].maxa=k;
s[p].maxb=max(s[p].maxb,k);
s[p].cov=1;
s[p].tag1=k;
s[p].tag2=0;
s[p].tag4=k;
return;
}
push_down(p);
update_cov(ql,qr,k,p*2),update_cov(ql,qr,k,p*2+1);
push_up(p);
}
下传代码:
inline void push_down(int p)
{
if(!s[p].cov)
{
int k2=s[p].tag2,k3=s[p].tag3;
s[p*2].maxb=max(s[p*2].maxb,s[p*2].maxa+k3);
s[p*2+1].maxb=max(s[p*2+1].maxb,s[p*2+1].maxa+k3);
s[p*2].maxa+=k2,s[p*2+1].maxa+=k2;
s[p*2].tag3=max(s[p*2].tag3,s[p*2].tag2+k3);
s[p*2+1].tag3=max(s[p*2+1].tag3,s[p*2+1].tag2+k3);
s[p*2].tag2+=k2,s[p*2+1].tag2+=k2;
s[p].tag2=s[p].tag3=0;
return;
}
int k1=s[p].tag1,k2=s[p].tag2,k3=s[p].tag3,k4=s[p].tag4;
s[p*2].maxb=max(s[p*2].maxb,s[p*2].maxa+k3);
s[p*2+1].maxb=max(s[p*2+1].maxb,s[p*2+1].maxa+k3);
s[p*2].tag3=max(s[p*2].tag3,s[p*2].tag2+k3);
s[p*2+1].tag3=max(s[p*2+1].tag3,s[p*2+1].tag2+k3);
//
s[p*2].maxa=s[p*2+1].maxa=k1+k2;
s[p*2].maxb=max(s[p*2].maxb,k4);
s[p*2+1].maxb=max(s[p*2+1].maxb,k4);
s[p*2].cov=s[p*2+1].cov=1;
s[p*2].tag1=s[p*2+1].tag1=k1;
s[p*2].tag2=s[p*2+1].tag2=k2;
s[p*2].tag4=s[p*2+1].tag4=k4;
s[p].cov=s[p].tag1=s[p].tag2=s[p].tag3=s[p].tag4=0;
}