Welfare State (Codeforces 1198B)
Tags: Others, binary search

There is a country with $$$n$$$ citizens. The $$$i$$$-th of them initially has $$$a_{i}$$$ 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 \le n \le 2 \cdot 10^{5}$$$) — the numer of citizens.The next line contains $$$n$$$ integers $$$a_1$$$, $$$a_2$$$, ..., $$$a_n$$$ ($$$0 \le a_{i} \le 10^{9}$$$) — the initial balances of citizens.The next line contains a single integer $$$q$$$ ($$$1 \le q \le 2 \cdot 10^{5}$$$) — 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 \le p \le n$$$, $$$0 \le x \le 10^{9}$$$), or 2 x ($$$0 \le x \le 10^{9}$$$). 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.

Note: In the first example the balances change as follows: 1 2 3 4 $$$\rightarrow$$$ 3 3 3 4 $$$\rightarrow$$$ 3 2 3 4 $$$\rightarrow$$$ 3 2 3 4In the second example the balances change as follows: 3 50 2 1 10 $$$\rightarrow$$$ 3 0 2 1 10 $$$\rightarrow$$$ 8 8 8 8 10 $$$\rightarrow$$$ 8 8 20 8 10

Sample Inputs:
4
1 2 3 4
3
2 3
1 2 2
2 1

5
3 50 2 1 10
3
1 2 0
2 8
1 3 20

Sample Outputs:
3 2 3 4

8 8 20 8 10

Solution (Python):
import sys
from math import inf
sys.setrecursionlimit(1000000)
input = lambda : sys.stdin.readline().strip()

def ls(root):
    return root << 1

def rs(root):
    return root << 1 | 1

def mid(l, r):
    return l + r >> 1

def pushup(root):
    tree[root] = min(tree[ls(root)], tree[rs(root)])

def pushdown(root):
    if min_tag[root] == 0:
        return
    min_tag[ls(root)] = max(min_tag[ls(root)], min_tag[root])
    min_tag[rs(root)] = max(min_tag[rs(root)], min_tag[root])
    tree[ls(root)] = max(tree[ls(root)], min_tag[root])
    tree[rs(root)] = max(tree[rs(root)], min_tag[root])
    min_tag[root] = 0

def build(root, l, r):
    if l == r:
        tree[root] = a[l]
        return
    build(ls(root), l, mid(l, r))
    build(rs(root), mid(l, r) + 1, r)
    pushup(root)

def update(root, l, r, ql, qr, k):
    if ql > r or qr < l:
        return
    if ql <= l and qr >= r:
        min_tag[root] = max(min_tag[root], k)
        tree[root] = max(tree[root], k)
        if ql == qr:
            tree[root] = k
        return
    pushdown(root)
    update(ls(root), l, mid(l, r), ql, qr, k)
    update(rs(root), mid(l, r) + 1, r, ql, qr, k)
    pushup(root)

def query(root, l, r, ql, qr):
    if ql > r or qr < l:
        return inf
    if ql <= l and qr >= r:
        return tree[root]
    pushdown(root)
    return min(query(ls(root), l, mid(l, r), ql, qr), query(rs(root), mid(l, r) + 1, r, ql, qr))

def solve():
    q = int(input())
    for _ in range(q):
        op = [*map(int, input().split())]
        if op[0] == 1:
            (x, k) = (op[1], op[2])
            update(1, 1, n, x, x, k)
        else:
            k = op[1]
            update(1, 1, n, 1, n, k)
    for i in range(1, n + 1):
        print(query(1, 1, n, i, i), end=' ')

def solve1():
    q = int(input())
    suf_max = [0] * q
    change_time = [0] * n
    for i in range(q):
        op = [*map(int, input().split())]
        if op[0] == 1:
            (x, k) = (op[1], op[2])
            x -= 1
            a[x] = k
            change_time[x] = i
        else:
            k = op[1]
            suf_max[i] = k
    for i in range(q - 2, -1, -1):
        suf_max[i] = max(suf_max[i], suf_max[i + 1])
    for (i, x) in enumerate(a):
        print(max(x, suf_max[change_time[i]]), end=' ')
if __name__ == '__main__':
    n = int(input())
    a = [*map(int, input().split())]
    t = 1
    for _ in range(t):
        solve1()

Solution (Python):
n = int(input())
nums = [int(x) for x in input().split()]
last = [0 for _ in range(n)]
payouts = []
nEvents = int(input())
for i in range(nEvents):
    info = [int(x) for x in input().split()]
    if info[0] == 1:
        nums[info[1] - 1] = info[2]
        last[info[1] - 1] = i
        payouts.append(0)
    else:
        payouts.append(info[1])
maiorApos = [-1 for _ in range(nEvents)]
maiorApos[-1] = payouts[-1]
for i in range(nEvents - 2, -1, -1):
    maiorApos[i] = max(payouts[i], maiorApos[i + 1])
for i in range(n):
    nums[i] = max(nums[i], maiorApos[last[i]])
print(*nums)

Solution (Python):
import sys
sys.setrecursionlimit(1000000)
from functools import *
from copy import deepcopy
from bisect import bisect_left, bisect_right
from math import inf, gcd, sqrt, ceil, floor, log
from string import ascii_lowercase, ascii_uppercase
from collections import deque, Counter, defaultdict
from itertools import accumulate, permutations, combinations
from heapq import heapify, heappush, heappop, nlargest, nsmallest

def I():
    return input()

def II():
    return int(input())

def MII():
    return map(int, input().split())

def LMII():
    return list(map(int, input().split()))

def FI():
    return sys.stdin.readline().split()

def FMII():
    return map(int, sys.stdin.readline().split())

def solve():
    n = II()
    a = LMII()
    m = II()
    change_time = [0] * n
    suf = [-inf] * (m + 1)
    for i in range(m):
        data = LMII()
        if len(data) == 2:
            x = int(data[1])
            suf[i] = x
        else:
            (p, x) = (int(data[1]), int(data[2]))
            a[p - 1] = x
            change_time[p - 1] = i
    for i in range(m - 1, -1, -1):
        suf[i] = max(suf[i + 1], suf[i])
    for i in range(n):
        a[i] = max(a[i], suf[change_time[i]])
    print(*a, sep=' ')
if __name__ == '__main__':
    solve()