题意:
1: x y 把 x 位置的数更新为 y
2: x 把序列中小于 x 的数更改为x
思路:
线段树单点更新查询,维护一个lazy标记和区间Min, 每次查询pushdown更新Min
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
using ll = long long;
int val[maxn<<2],lazy[maxn<<2],Min[maxn<<2];
int n,q,a[maxn];
void pushup(int rt){
Min[rt] = min(Min[rt<<1],Min[rt<<1|1]);
}
void pushdown(int rt){
if(lazy[rt]){
Min[rt<<1] = max(Min[rt<<1],lazy[rt]);
Min[rt<<1|1] = max(Min[rt<<1|1],lazy[rt]);
lazy[rt<<1] = max(lazy[rt<<1],lazy[rt]);
lazy[rt<<1|1] = max(lazy[rt<<1|1],lazy[rt]);
lazy[rt] = 0;
}
}
void build(int l,int r,int rt){
lazy[r] = 0;
if(l == r){
Min[rt] = a[l];
//lazy[rt] = 0;
return;
}
int mid = (l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
void update_point(int l,int r,int rt,int pos,int v){
if(l == r){
Min[rt] = v;
return;
}
pushdown(rt);
int mid = (l+r)>>1;
if(pos <= mid) update_point(l,mid,rt<<1,pos,v);
else update_point(mid+1,r,rt<<1|1,pos,v);
pushup(rt);
}
void update_small(int rt,int v){
if(Min[rt] >= v) return;
Min[rt] = v;
lazy[rt] = max(lazy[rt],v);
}
int query(int l,int r,int rt,int pos){
if(l == r){
return Min[rt];
}
pushdown(rt);
int mid = (l+r)>>1;
if(pos <= mid) return query(l,mid,rt<<1,pos);
else return query(mid+1,r,rt<<1|1,pos);
}
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
build(1,n,1);
scanf("%d",&q);
while(q--){
int op,x,y;
scanf("%d",&op);
if(op == 1){
scanf("%d%d",&x,&y);
update_point(1,n,1,x,y);
}else{
scanf("%d",&x);
update_small(1,x);
}
// for(int i = 1; i <= n; i++){
// printf("%d ",query(1,n,1,i));
// }
// puts("");
}
for(int i = 1; i <= n; i++){
printf("%d ",query(1,n,1,i));
}
}