There is a country with n citizens. The i-th of them initially has ai money. The government strictly controls the wealth of its citizens. Whenever a citizen makes a purchase or earns some money, they must send a receipt to the social services mentioning the amount of money they currently have.
Sometimes the government makes payouts to the poor: all citizens who have strictly less money than x are paid accordingly so that after the payout they have exactly x money. In this case the citizens don’t send a receipt.
You know the initial wealth of every citizen and the log of all events: receipts and payouts. Restore the amount of money each citizen has after all events.
Input
The first line contains a single integer n (1≤n≤2⋅105) — the numer of citizens.
The next line contains n integers a1, a2, …, an (0≤ai≤109) — the initial balances of citizens.
The next line contains a single integer q (1≤q≤2⋅105) — the number of events.
Each of the next q lines contains a single event. The events are given in chronological order.
Each event is described as either 1 p x (1≤p≤n, 0≤x≤109), or 2 x (0≤x≤109). In the first case we have a receipt that the balance of the p-th person becomes equal to x. In the second case we have a payoff with parameter x.
Output
Print n integers — the balances of all citizens after all events.
Examples
inputCopy
4
1 2 3 4
3
2 3
1 2 2
2 1
outputCopy
3 2 3 4
inputCopy
5
3 50 2 1 10
3
1 2 0
2 8
1 3 20
outputCopy
8 8 20 8 10
Note
In the first example the balances change as follows: 1 2 3 4 → 3 3 3 4 → 3 2 3 4 → 3 2 3 4
In the second example the balances change as follows: 3 50 2 1 10 → 3 0 2 1 10 → 8 8 8 8 10 → 8 8 20 8 10
题意: 题意很简单,有一个长度为n的序列,两种操作,一个是单点更新,讲a[i]跟新为x。第二种操作,将1~n中,小于x的数全部跟新为x。
思路:
单点跟新就不用说了,这里主要说第二中操作。
维护区间min,如果说节点中的min需要跟新的话,那么就说明,当前区间中有值需要跟新,就需要一直递归。但是这种显然是会T掉的,所以还需要维护一个max。
如果该节点的max < x的话,那么整个区间就需要全部跟新,不需要再进行递归;如果该节点的min < x,则说明区间中有值需要跟新,则进入该节点;如果该节点最小值都不需要跟新的话,则区间不需要跟新。
总结反思: 线段树的代码量实在是太大了,这道题差不多写了半小时,最后优化,该BUG又是半小时,结果在比赛结束后10分钟左右才出来的吧,看来还是要学习一下树状数组的啊。后来问了大佬做法,听说是维护最大值和前缀最大值…懵逼,没听说过前缀最大值啊…
#include<bits/stdc++.h>
using namespace std;
#define lson (rt<<1)
#define rson ((rt<<1)|1)
const int MAXN = 210000;
struct node
{
int x,y,layz;
}tree[MAXN<<2];
void pushup(int rt)
{
tree[rt].x = max(tree[lson].x,tree[rson].x);
tree[rt].y = min(tree[lson].y,tree[rson].y);
}
void build(int rt,int L,int R)
{
if(L ==R){
scanf("%d",&tree[rt].x);
tree[rt].y = tree[rt].x;
tree[rt].layz = 0;
return ;
}
int Mid = (L+R)>>1;
build(lson,L,Mid);
build(rson,Mid+1,R);
pushup(rt);
}
void pushdown(int rt)
{
if(tree[rt].layz){
tree[lson].layz = tree[rson].layz = tree[rt].layz;
tree[lson].x = tree[rson].x = tree[rt].layz;
tree[lson].y = tree[rson].y = tree[rt].layz;
tree[rt].layz = 0;
return ;
}
}
void update(int rt,int L,int R,int x,int w)
{
if(L==R){
tree[rt].y = tree[rt].x = w;
return ;
}
pushdown(rt);
int Mid = (L+R)>>1;
if(x <= Mid) update(lson,L,Mid,x,w);
else update(rson,Mid+1,R,x,w);
pushup(rt);
}
void update1(int rt,int L,int R,int l,int r,int x)
{
pushdown(rt);
if(L==R) return ;
int Mid = (L+R)>>1;
if(tree[lson].x <= x){
tree[lson].x = tree[lson].y = tree[lson].layz = x;
}
else if(tree[lson].y < x) update1(lson,L,Mid,l,r,x);
if(tree[rson].x <= x){
tree[rson].x = tree[rson].y = tree[rson].layz = x;
}
else if(tree[rson].y < x) update1(rson,Mid+1,R,l,r,x);
pushup(rt);
}
void query(int rt,int L,int R,int l,int r)
{
if(L == R){
printf("%d ",tree[rt].x);
return ;
}
pushdown(rt);
int Mid = (L+R)>>1;
query(lson,L,Mid,l,r);
query(rson,Mid+1,R,l,r);
}
int main()
{
int n;
scanf("%d",&n);
build(1,1,n);
int T;
scanf("%d",&T);
while(T--){
int t;
scanf("%d",&t);
if(t == 1){
int p,x;
scanf("%d%d",&p,&x);
update(1,1,n,p,x);
}
else{
int x;
scanf("%d",&x);
if(tree[1].x <= x) tree[1].x = tree[1].layz = x;
else update1(1,1,n,1,n,x);
}
}
query(1,1,n,1,n);
printf("\n");
return 0;
}