我们发现依次修改影响的是时间线段树一段区间要取 min,这个用吉司机线段树维护就好了.
具体地,我们记录一个 tag 标记,然后下传条件是 mx[now]<mx[lson] 或 mx[now]<mx[rson].
这道题卡常,最好不要用 vector 来存储操作.
code:
#include <bits/stdc++.h>
#define N 2000009
#define ll long long
#define lson now<<1
#define rson now<<1|1
#define inf 2000000009
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int n,m,Q;
int mx[N<<2],se[N<<2],tag[N<<2],a[N];
void pushup(int now)
{
mx[now]=max(mx[lson],mx[rson]);
if(mx[lson]==mx[rson]) se[now]=max(se[lson],se[rson]);
else if(mx[lson]<mx[rson]) se[now]=max(mx[lson],se[rson]);
else se[now]=max(mx[rson],se[lson]);
}
void pushdown(int now)
{
if(mx[lson]>mx[now]) mx[lson]=mx[now],tag[lson]+=tag[now];
if(mx[rson]>mx[now]) mx[rson]=mx[now],tag[rson]+=tag[now];
tag[now]=0;
}
void update(int l,int r,int now,int L,int R,int v)
{
if(mx[now]<=v) return;
if(l>=L&&r<=R&&se[now]<v)
{
mx[now]=v,++tag[now];
return;
}
pushdown(now);
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,lson,L,R,v);
if(R>mid) update(mid+1,r,rson,L,R,v);
pushup(now);
}
int query(int l,int r,int now,int p)
{
if(l==r) return tag[now];
int mid=(l+r)>>1;
pushdown(now);
if(p<=mid) return query(l,mid,lson,p);
else return query(mid+1,r,rson,p);
}
void build(int l,int r,int now)
{
mx[now]=inf,se[now]=-inf;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
}
int Ans[N];
vector<int>q[N];
struct data
{
int x,t;
data(int x=0,int t=0):x(x),t(t){}
bool operator<(const data b) const { return t<b.t; }
}er[N];
int hd[N],nex[N],edges;
void add(int u,data e)
{
nex[++edges]=hd[u],hd[u]=edges,er[edges]=e;
}
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd()
{
int x=0; char c;
while(c<48) c=nc();
while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();
return x;
}
int main()
{
// setIO("input");
int x,y,z;
n=rd(),m=rd();
for(int i=1;i<=n;++i) a[i]=rd(),add(i,data(a[i],0));
for(int i=1;i<=m;++i)
{
x=rd();
if(x==1) y=rd(),z=rd(),add(y,data(z,i)); // z 时刻开始生效
if(x==2) y=rd(),q[y].push_back(i);
}
build(0,m,1);
for(int i=n;i>=1;--i)
{
int pr=m;
for(int j=hd[i];j;j=nex[j])
{
data e=er[j];
int r=pr,l=e.t;
update(0,m,1,l,r,e.x);
pr=e.t-1;
}
for(int j=0;j<q[i].size();++j) Ans[q[i][j]]=query(0,m,1,q[i][j]);
}
for(int i=1;i<=m;++i) if(Ans[i]) printf("%d
",Ans[i]);
return 0;
}