結果

問題 No.1804 Intersection of LIS
ユーザー noriocnorioc
提出日時 2024-07-19 03:02:02
言語 PyPy3
(7.3.15)
結果
RE  
実行時間 -
コード長 1,657 bytes
コンパイル時間 307 ms
コンパイル使用メモリ 82,304 KB
実行使用メモリ 65,536 KB
最終ジャッジ日時 2024-07-19 03:02:18
合計ジャッジ時間 4,756 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
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 -
testcase_29 RE -
testcase_30 RE -
testcase_31 RE -
testcase_32 RE -
testcase_33 RE -
testcase_34 RE -
testcase_35 RE -
testcase_36 RE -
testcase_37 RE -
testcase_38 RE -
testcase_39 RE -
権限があれば一括ダウンロードができます

ソースコード

diff #

from collections import defaultdict, Counter
from bisect import bisect_left
from atcoder.segtree import SegTree


def lis_ranks(a: list) -> list:
    """LIS のランクを返す"""
    n = len(a)
    ranks = [0] * n  # ranks[i] : A[i] が LIS の何番目か
    dp = [INF] * n
    for i in range(n):
        ranks[i] = bisect_left(dp, a[i])
        dp[ranks[i]] = a[i]

    return ranks


def lis_candidates(a: list[int], ranks: list[int]) -> list[int]:
    """LIS の構成要素となりうる要素のインデックスを返す"""
    n = len(a)
    max_rank = max(ranks)

    d = defaultdict(set)  # key=ランク val=そのランクのインデックス集合
    res = []
    for i in range(n):
        d[ranks[i]].add(i)
        if ranks[i] == max_rank:
            res.append(i)

    segt = SegTree(max, 0, n+1)
    for rank in reversed(range(max_rank)):  # 大きい順にみていく
        for i in d[rank+1]:
            segt.set(i, a[i])

        for i in list(d[rank]):
            x = segt.prod(i+1, n)  # i より右側に a[i] より大きい値が存在するか
            if a[i] < x:
                res.append(i)
            else:
                d[rank].remove(i)  # LIS の要素ではないので削除

        # 戻す
        for i in d[rank+1]:
            segt.set(i, 0)

    return sorted([i for i in res])


INF = 1 << 60
N = int(input())
A = list(map(int, input().split()))
ranks = lis_ranks(A)
inds = lis_candidates(A, ranks)

freq = Counter()
for i in inds:
    freq[ranks[i]] += 1

ans = []
for i in inds:
    if freq[ranks[i]] == 1:  # 唯一のランクか?
        ans.append(A[i])

print(len(ans))
print(*ans)
0