結果

問題 No.318 学学学学学
ユーザー hagebooihagebooi
提出日時 2019-03-01 17:31:52
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
TLE  
実行時間 -
コード長 3,198 bytes
コンパイル時間 86 ms
コンパイル使用メモリ 12,800 KB
実行使用メモリ 75,012 KB
最終ジャッジ日時 2024-06-23 12:07:39
合計ジャッジ時間 13,138 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 626 ms
51,312 KB
testcase_01 AC 757 ms
45,904 KB
testcase_02 AC 809 ms
45,916 KB
testcase_03 AC 694 ms
45,012 KB
testcase_04 AC 780 ms
45,392 KB
testcase_05 TLE -
testcase_06 TLE -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

import numpy
from collections import defaultdict

"""

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