http://codeforces.com/problemset/problem/1198/B
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
Input
4
1 2 3 4
3
2 3
1 2 2
2 1
Output
3 2 3 4
Input
5
3 50 2 1 10
3
1 2 0
2 8
1 3 20
Output
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
n
n个数,两种操作,(1)修改第
i
i
i个数的值。(2)把所有
<
x
<x
<x的数变为
x
x
x。问最终的序列。
思路:单点修改+区间修改+单点查询,可以用线段树来做。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
struct node
{
int l,r,MIN,lazy;
}tree[maxn<<2];
void up(int i)
{
tree[i].MIN=min(tree[i<<1].MIN,tree[i<<1|1].MIN);
}
void down(int i)
{
tree[i<<1].lazy=max(tree[i<<1].lazy,tree[i].lazy);
tree[i<<1|1].lazy=max(tree[i<<1|1].lazy,tree[i].lazy);
tree[i<<1].MIN=max(tree[i].lazy,tree[i<<1].MIN);
tree[i<<1|1].MIN=max(tree[i].lazy,tree[i<<1|1].MIN);
tree[i].lazy=0;
}
void build(int i,int l,int r)
{
tree[i].l=l,tree[i].r=r,tree[i].lazy=0;
if(l==r)
{
scanf("%d",&tree[i].MIN);
return ;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
up(i);
}
void update(int i,int pos,int v)
{
if(tree[i].l==tree[i].r)
{
tree[i].MIN=v;
return ;
}
if(tree[i].lazy)
down(i);
int mid=tree[i].l+tree[i].r>>1;
if(pos<=mid)
update(i<<1,pos,v);
else
update(i<<1|1,pos,v);
up(i);
}
void update(int v)
{
if(v<=tree[1].MIN)
return ;
tree[1].MIN=v;
tree[1].lazy=max(tree[1].lazy,v);
}
int query(int i,int pos)
{
if(tree[i].l==tree[i].r)
return tree[i].MIN;
if(tree[i].lazy)
down(i);
int mid=tree[i].l+tree[i].r>>1;
if(pos<=mid)
return query(i<<1,pos);
else
return query(i<<1|1,pos);
}
int main()
{
int n,q,op,x,y;
scanf("%d",&n);
build(1,1,n);
scanf("%d",&q);
while(q--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d %d",&x,&y);
update(1,x,y);
}
else
{
scanf("%d",&x);
update(x);
}
}
for(int i=1;i<=n;i++)
{
printf("%d ",query(1,i));
}
return 0;
}