随便说点
昨天晚上 A A A的,不过因为有点晚了就没写博客,今晚一起写了。
题意
给出一个序列,有两种操作,一种是将节点 x x x更改为更改为 y y y,另一种是将所有小于 y y y的位置更改为 y y y。
题解
开始时候想的是线段树,不过后来一直没动手,要是谁感觉合适可以试一下,下面讲一下我听蜗老师讲的思路。
一个位置可能有很多次单点修改,在最后一次单点修改之前无论做什么操作都没有意义。同时,在没有单点修改的情况下,一连串连续的第二类操作只有值最大的那个才有意义。所以我们只要关注每个位置最后一次被修改的值以及被修改之后的所有第二类的操作的最大值,所以我们只要记录一下每个点最后一次单点修改的值以及修改的时间,并且按照时间从后向前的顺序维护后缀最大值,得出最后每个位置的答案。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int t[N],maxi[N];
int num[N],flag[N];
int n,q;
int main(){
#ifdef LOCAL
freopen("x.in","r",stdin);
#endif
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>num[i];
for(int i=1;i<=n;i++){
int op;
cin>>op;
if(op==1){
int x,y;
cin>>x>>y;
num[x]=y;
t[x]=i;
}else{
int y;
cin>>y;
maxi[i]=y;
}
}
for(int i=n;i>=0;i--) maxi[i]=max(maxi[i],maxi[i+1]);
for(int i=1;i<=n;i++) num[i]=max(num[i],maxi[t[i]]);
for(int i=1;i<=n;i++) cout<<num[i]<<" ";
cout<<endl;
return 0;
}