結果

問題 No.318 学学学学学
ユーザー hagebooihagebooi
提出日時 2019-03-01 17:35:12
言語 PyPy3
(7.3.15)
結果
RE  
実行時間 -
コード長 3,198 bytes
コンパイル時間 351 ms
コンパイル使用メモリ 86,952 KB
実行使用メモリ 78,876 KB
最終ジャッジ日時 2023-09-05 16:38:06
合計ジャッジ時間 7,129 ms
ジャッジサーバーID
(参考情報)
judge12 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 RE -
testcase_01 RE -
testcase_02 RE -
testcase_03 RE -
testcase_04 RE -
testcase_05 RE -
testcase_06 RE -
testcase_07 RE -
testcase_08 RE -
testcase_09 RE -
testcase_10 RE -
testcase_11 RE -
testcase_12 RE -
testcase_13 RE -
testcase_14 RE -
testcase_15 RE -
testcase_16 RE -
testcase_17 RE -
testcase_18 RE -
testcase_19 RE -
testcase_20 RE -
testcase_21 RE -
testcase_22 RE -
testcase_23 RE -
testcase_24 RE -
testcase_25 RE -
testcase_26 RE -
testcase_27 RE -
testcase_28 RE -
権限があれば一括ダウンロードができます

ソースコード

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