結果

問題 No.318 学学学学学
ユーザー hagebooihagebooi
提出日時 2019-03-01 17:36:24
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,110 ms / 2,000 ms
コード長 3,148 bytes
コンパイル時間 481 ms
コンパイル使用メモリ 87,216 KB
実行使用メモリ 108,920 KB
最終ジャッジ日時 2023-09-04 21:23:42
合計ジャッジ時間 13,577 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 182 ms
79,676 KB
testcase_01 AC 254 ms
83,704 KB
testcase_02 AC 301 ms
85,500 KB
testcase_03 AC 220 ms
81,828 KB
testcase_04 AC 285 ms
84,536 KB
testcase_05 AC 1,100 ms
108,424 KB
testcase_06 AC 800 ms
102,640 KB
testcase_07 AC 577 ms
98,980 KB
testcase_08 AC 399 ms
97,468 KB
testcase_09 AC 281 ms
96,152 KB
testcase_10 AC 197 ms
94,604 KB
testcase_11 AC 1,110 ms
108,920 KB
testcase_12 AC 651 ms
104,256 KB
testcase_13 AC 533 ms
99,188 KB
testcase_14 AC 394 ms
99,452 KB
testcase_15 AC 283 ms
95,576 KB
testcase_16 AC 220 ms
95,592 KB
testcase_17 AC 567 ms
106,652 KB
testcase_18 AC 498 ms
106,500 KB
testcase_19 AC 586 ms
106,440 KB
testcase_20 AC 195 ms
94,512 KB
testcase_21 AC 73 ms
71,444 KB
testcase_22 AC 72 ms
71,288 KB
testcase_23 AC 73 ms
71,480 KB
testcase_24 AC 73 ms
71,288 KB
testcase_25 AC 73 ms
71,156 KB
testcase_26 AC 73 ms
71,124 KB
testcase_27 AC 73 ms
71,256 KB
testcase_28 AC 74 ms
71,152 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

"""

g(f(a, b), c) = f(g(a, c), g(b, c))
...cを後から作用させても、先に作用させても結果は同じ。(両方に作用させることに注意)
g(g(a, b), c) = g(a, h(b, c))
...b, cを順番に作用させることはh(b,c)を一回作用させることと同じ。(計算の省略が可能)

例)
例えば区間の最大値を求める + 区間を変更するというクエリでは
f(a, b) = max(a, b) (単位元は0)
g(a, c) = c(ただしc = 0ならばa)
g = h

今回は区間に対してはなにもしない + 区間を変更するというクエリである。
したがって
f(a, b) = 0
g(a, c) = c(ただしc = 0ならばa)
g = h
とすれば良い。(最下段はfの影響を受けない。)

"""

class segtree:
    def __init__(self, n, L = None):
        self.raw_len = n
        self.list = L
        self.init()

    def init(self):
        N = 1
        n = self.raw_len
        while N < n:
            N *= 2
        self.len = N
        self.node = [0]*(2*N-1)
        self.lazy = [0]*(2*N-1)
        if self.list:
            for i in range(self.raw_len):
                self.node[i+self.len-1] = self.list[i]
            for i in range(self.len - 2, -1, -1):
                self.node[i] = 0

    def update(self, i, x):#点更新
        i += self.len - 1
        self.node[i] = x
        while i > 0:
            i = (i-1)//2
            self.node[i] = 0

    def eval(self, k):
        if self.lazy[k] != 0:
            self.node[k] = self.lazy[k]
            if k < self.len - 1:
                #要編集。和なら半数伝播、minmaxなら全数伝播。
                self.lazy[2*k+1] = self.lazy[k]
                self.lazy[2*k+2] = self.lazy[k]
            self.lazy[k] = 0

    def range_update(self, a, b, x, k=0, l=0, r=None):
        if r == None:
            r =  self.len
        self.eval(k)
        if r <= a or b <= l:
            return 0
        if a <= l and r <= b:
            self.lazy[k] = x #max,minなら(r-l)は書かなくて良い
            self.eval(k)
        else:
            self.range_update(a, b, x, k*2+1, l, (l+r)//2)
            self.range_update(a, b, x, k*2+2, (l+r)//2, r)
            self.node[k] = 0
 
    def query(self, a, b, k = 0, l = 0, r = None):
        if r == None:
            r = self.len
        if r <= a or b <= l:
            return 0
        self.eval(k, l, r)
        if a <= l and r <= b:
            return self.node[k]
        else:
            vl = self.query(a, b, k*2+1, l, (l+r)//2)
            vr = self.query(a, b, k*2+2, (l+r)//2, r)
            return 0
    
    def nodes(self):
        for i in range(2*self.len-1):
            self.eval(i)
        res = self.node[self.len-1:]
        return list(res)

N = int(input())
a = [int(i) for i in input().split()]
dr = {} #数numのうち最も右にあるものはdr[num]
dl = {}
for i, num in enumerate(a):
    dr[num] = i
ar = a[::-1]
for i, num in enumerate(ar):
    dl[num] = N-1-i
seg = segtree(N)
for num, _ in sorted(dr.items()):
    l = dl[num]
    r = dr[num]
    seg.range_update(l, r+1, num)
ans = seg.nodes()
ans = [str(i) for i in ans if i]
print(" ".join(ans))
0