参考了这篇题解
提交记录
代码如下
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mid ((l+r)/2)
#define FOR(qw,we,er) for(int qw=we;qw<=er;++qw)
int t1,t2,t3,n,q;
int s[800100];
void killthis(int k);
struct xianduan_tree
{
int maxx[800100],minn[800100],tag[800100],maxxx;
bool tagc[800100];
void push_down(int k)
{
if(tagc[k]==1)
{
tagc[k]=0;
tagc[k*2]=tagc[k*2+1]=1;
tag[k*2]=tag[k*2+1]=maxx[k*2]=maxx[k*2+1]=minn[k*2]=minn[k*2+1]=0;
return;
}
maxx[k*2]+=tag[k];
maxx[k*2+1]+=tag[k];
minn[k*2]+=tag[k];
minn[k*2+1]+=tag[k];
tag[k*2]+=tag[k];
tag[k*2+1]+=tag[k];
tag[k]=0;
}
void push_up(int k)
{
maxx[k]=max(maxx[k*2],maxx[k*2+1]);
minn[k]=min(minn[k*2],minn[k*2+1]);
s[k]=s[k*2]+s[k*2+1];
}
void build(int k,int l,int r)
{
maxxx=max(maxxx,k);
s[k]=r-l+1;
if(l==r)return;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
}
void add(int k,int l,int r,int ll,int rr,int qw)
{
if(r<ll||l>rr||s[k]==0)return;
if(ll<=l&&r<=rr)
{
maxx[k]+=qw;
minn[k]+=qw;
tag[k]+=qw;
return;
}
if(l!=r)
{
push_down(k);
add(k*2,l,mid,ll,rr,qw);
add(k*2+1,mid+1,r,ll,rr,qw);
push_up(k);
}
}
void kill(int k,int l,int r,int ll,int rr,int qw)
{
if(r<ll||l>rr||s[k]==0)return;
if(maxx[k]>=qw)
{
if(minn[k]>=qw&&ll<=l&&r<=rr)
{
killthis(k);
return;
}
if(l!=r)
{
push_down(k);
kill(k*2,l,mid,ll,rr,qw);
kill(k*2+1,mid+1,r,ll,rr,qw);
push_up(k);
}
}
else return;
}
void clean(int k,int l,int r,int ll,int rr)
{
if(r<ll||l>rr||s[k]==0)return;
if(ll<=l&&r<=rr)
{
maxx[k]=minn[k]=0;
tag[k]=0;
tagc[k]=1;
return;
}
if(l!=r)
{
push_down(k);
clean(k*2,l,mid,ll,rr);
clean(k*2+1,mid+1,r,ll,rr);
push_up(k);
}
}
void debug()
{
printf("maxx[]:");
FOR(i,1,maxxx)printf("%lld ",maxx[i]);
printf("\nminn[]:");
FOR(i,1,maxxx)printf("%lld ",minn[i]);
printf("\ns[]:");
FOR(i,1,maxxx)printf("%lld ",s[i]);
printf("\n");
}
}a,b;
void killthis(int k)
{
a.tagc[k]=0;
b.tagc[k]=0;
a.tag[k]=0;
b.tag[k]=0;
s[k]=0;
a.maxx[k]=0;
a.minn[k]=INT_MAX;
b.maxx[k]=0;
b.minn[k]=INT_MAX;
}
signed main()
{
scanf("%lld%lld",&n,&q);
a.build(1,1,n);
b.build(1,1,n);
FOR(i,1,q)
{
scanf("%lld",&t1);
if(t1==1)
{
scanf("%lld%lld%lld",&t1,&t2,&t3);
a.add(1,1,n,t1,t2,t3);
b.add(1,1,n,1,t1-1,t3);
b.add(1,1,n,t2+1,n,t3);
b.clean(1,1,n,t1,t2);
a.clean(1,1,n,1,t1-1);
a.clean(1,1,n,t2+1,n);
}
else if(t1==2)
{
scanf("%lld%lld%lld",&t1,&t2,&t3);
a.kill(1,1,n,t1,t2,t3);
b.kill(1,1,n,t1,t2,t3);
}
else if(t1==3)
{
printf("%lld\n",s[1]);
}
}
return 0;
}