传送门 http://www.lydsy.com/JudgeOnline/problem.php?id=4355
吉司机线段树(去年又在现场系列)
某Q:线段树带来的沉重打击
写得巨挫,下次肯定会去换个姿势的QwQ
#include<stdio.h>
#include<algorithm>
#define inf 233333333333333333LL
#define lim 1
#define Lson t[k].lson
#define Rson t[k].rson
#define N 300005
typedef long long ll;
using namespace std;
inline void read(int &x)
{
x=0;int f=1;char ch=getchar();
for (;ch<'0' || '9'<ch;ch=getchar()) if (ch=='-') f=-1;
for (;'0'<=ch && ch<='9';ch=getchar()) x=x*10+ch-'0';
x*=f;
}
struct tree
{
int lson,rson,tot,cc;
ll tagm,fi,se,taga;
}t[N<<1];
int tot,n,L,R,X,a[N],m,Root,type,Ans;
inline void ms(const int &k,const int &l,const int &r);
inline void push(const int &k,const int &l,const int &r)
{
t[Lson].cc=t[Rson].cc=t[k].cc;
t[k]=(tree){t[k].lson,t[k].rson,r-l+1,-1,-inf,t[k].cc,23333333333333333LL,0};
}
void maintain(const int &k,const int &l,const int &r)
{
if (l==r)
{
if (t[k].cc!=-1) t[k].fi=t[k].cc;
else t[k].fi=max(t[k].taga+t[k].fi,(ll)t[k].tagm);
t[k].taga=0;t[k].tagm=-inf;
t[k].cc=-1;
return;
}
int mid=(l+r)>>1;
if (t[k].taga || -lim<t[k].tagm || t[k].cc!=-1)
{
if (t[k].cc!=-1)
{
push(k,l,r);
return;
}
t[k].fi+=t[k].taga;
t[k].se+=t[k].taga;
if (t[Lson].cc!=-1) push(Lson,l,mid);
if (t[Rson].cc!=-1) push(Rson,mid+1,r);
t[Lson].tagm+=t[k].taga;
t[Rson].tagm+=t[k].taga;
t[Lson].taga+=t[k].taga;
t[Rson].taga+=t[k].taga;
t[k].taga=0;
if (t[k].tagm<=t[k].fi) t[k].tagm=-inf;
if (t[k].fi<t[k].tagm && t[k].tagm<t[k].se)
{
t[k].fi=t[k].tagm;
t[Lson].tagm=max(t[Lson].tagm,t[k].tagm);
t[Rson].tagm=max(t[Rson].tagm,t[k].tagm);
}
if (t[k].se<=t[k].tagm)
{
t[Lson].tagm=max(t[Lson].tagm,t[k].tagm);
t[Rson].tagm=max(t[Rson].tagm,t[k].tagm);
maintain(Lson,l,mid);
maintain(Rson,mid+1,r);
ms(k,l,r);
}
t[k].tagm=-inf;
}
}
inline void ms(const int &k,const int &l,const int &r)
{
int p1=Lson,p2=Rson,mid=l+r>>1;
maintain(p1,l,mid);
maintain(p2,mid+1,r);
if (t[p2].fi<t[p1].fi) swap(p1,p2);
t[k].fi=t[p1].fi;
if (t[p1].fi==t[p2].fi)
{
t[k].se=min(t[p1].se,t[p2].se);
t[k].tot=t[p1].tot+t[p2].tot;
}
else
{
t[k].tot=t[p1].tot;
t[k].se=min(t[p1].se,t[p2].fi);
}
}
void build(int &k,const int &l,const int &r)
{
k=++tot;
if (l==r)
{
t[k]=(tree){0,0,1,-1,-inf,a[l],23333333333333333LL,0};
return;
}
int mid=l+r>>1;
build(Lson,l,mid);
build(Rson,mid+1,r);
t[k].tagm=-inf;
t[k].cc=-1;
ms(k,l,r);
}
void add(const int &k,const int &l,const int &r)
{
if (t[k].taga || -lim<t[k].tagm || t[k].cc!=-1) maintain(k,l,r);
if (L<=l && r<=R)
{
t[k].taga+=X;
t[k].tagm=0;
maintain(k,l,r);
return;
}
int mid=l+r>>1;
if (L<=mid) add(Lson,l,mid);
if (mid<R) add(Rson,mid+1,r);
ms(k,l,r);
}
void change(const int &k,const int &l,const int &r)
{
if (t[k].taga || -lim<t[k].tagm || t[k].cc!=-1) maintain(k,l,r);
if (L<=l && r<=R)
{
t[k].cc=X;
maintain(k,l,r);
return;
}
int mid=l+r>>1;
if (L<=mid) change(Lson,l,mid);
if (mid<R) change(Rson,mid+1,r);
ms(k,l,r);
}
void Min(const int &k,const int &l,const int &r)
{
if (t[k].taga || -lim<t[k].tagm || t[k].cc!=-1) maintain(k,l,r);
if (L<=l && r<=R)
{
if (t[k].fi==0) Ans+=t[k].tot;
return;
}
int mid=l+r>>1;
if (L<=mid) Min(Lson,l,mid);
if (mid<R) Min(Rson,mid+1,r);
}
int main()
{
read(n),read(m);
for (int i=1;i<=n;i++) read(a[i]);
build(Root,1,n);
while (m--)
{
read(type);read(L),read(R);
if (type==1) read(X),change(1,1,n);
if (type==2) read(X),add(1,1,n);
if (type==3) Ans=0,Min(1,1,n),printf("%d\n",Ans);
}
}