結果
| 問題 |
No.3188 K-th Lexmin
|
| コンテスト | |
| ユーザー |
蜜蜂
|
| 提出日時 | 2025-06-13 16:35:29 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,892 ms / 3,500 ms |
| コード長 | 3,324 bytes |
| コンパイル時間 | 422 ms |
| コンパイル使用メモリ | 82,664 KB |
| 実行使用メモリ | 288,076 KB |
| 最終ジャッジ日時 | 2025-08-29 05:46:54 |
| 合計ジャッジ時間 | 67,672 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 47 |
ソースコード
import sys
input = sys.stdin.buffer.readline
from collections import Counter
# https://tjkendev.github.io/procon-library/python/string/sa_sa-is.html
def sais(s):
uniq = list(set(s))
uniq.sort()
return sais_rec(list(map({e: i+1 for i, e in enumerate(uniq)}.__getitem__, s)), len(uniq))
def sais_rec(lst, num):
L = len(lst)
if L < 2:
return lst + [0]
lst = lst + [0]
L += 1
res = [-1] * L
t = [1] * L
for i in range(L-2, -1, -1):
t[i] = 1 if (lst[i] < lst[i+1] or (lst[i] == lst[i+1] and t[i+1])) else 0
isLMS = [t[i-1] < t[i] for i in range(L)]
LMS = [i for i in range(1, L) if t[i-1] < t[i]]
LMSn = len(LMS)
count = Counter(lst)
tmp = 0
cstart = [0]*(num+1)
cend = [0]*(num+1)
for key in range(num+1):
cstart[key] = tmp
cend[key] = tmp = tmp + count[key]
cc_it = [iter(range(e-1, s-1, -1)) for s, e in zip(cstart, cend)]
for e in reversed(LMS):
res[next(cc_it[lst[e]])] = e
cs_it = [iter(range(s, e)) for s, e in zip(cstart, cend)]
ce_it = [iter(range(e-1, s-1, -1)) for s, e in zip(cstart, cend)]
for e in res:
if e > 0 and not t[e-1]:
res[next(cs_it[lst[e-1]])] = e-1
for e in reversed(res):
if e > 0 and t[e-1]:
res[next(ce_it[lst[e-1]])] = e-1
name = 0; prev = -1
pLMS = {}
for e in res:
if isLMS[e]:
if prev == -1 or lst[e] != lst[prev]:
name += 1; prev = e
else:
for i in range(1, L):
if lst[e+i] != lst[prev+i]:
name += 1; prev = e
break
if isLMS[e+i] or isLMS[prev+i]:
break
pLMS[e] = name-1
if name < LMSn:
sublst = [pLMS[e] for e in LMS if e < L-1]
ret = sais_rec(sublst, name-1)
LMS = list(map(LMS.__getitem__, reversed(ret)))
else:
LMS = [e for e in reversed(res) if isLMS[e]]
res = [-1] * L
cc_it = [iter(range(e-1, s-1, -1)) for s, e in zip(cstart, cend)]
for e in LMS:
res[next(cc_it[lst[e]])] = e
cs_it = [iter(range(s, e)) for s, e in zip(cstart, cend)]
ce_it = [iter(range(e-1, s-1, -1)) for s, e in zip(cstart, cend)]
for e in res:
if e > 0 and not t[e-1]:
res[next(cs_it[lst[e-1]])] = e-1
for e in reversed(res):
if e > 0 and t[e-1]:
res[next(ce_it[lst[e-1]])] = e-1
return res
def solve():
n, k = map(int, input().split())
a = list(map(int, input().split()))
for i in range(n):
a[i] -= 1
sa = sais(a)[1:]
len = [n - sa[i] for i in range(n)]
lensum = [0] * (n + 1)
for i in range(n):
lensum[i + 1] = lensum[i] + len[i]
l, r = 0, n - 1
rem = k
ans = []
for i in range(n):
def rng(val):
ok, ng = l - 1, r + 1
while ng - ok > 1:
check = (ok + ng) // 2
if sa[check] + i >= n or a[sa[check] + i] <= val:
ok = check
else:
ng = check
return ok
def num(val):
right = rng(val)
res = lensum[right + 1] - lensum[l] - (right - l + 1) * i
return res
ok, ng = -1, n + 1
while ng - ok > 1:
check = (ok + ng) // 2
if num(check) < rem:
ok = check
else:
ng = check
ans.append(ng + 1)
rem -= num(ok)
left = rng(ok) + 1
right = rng(ng)
l, r = left, right
rem -= r - l + 1
if rem <= 0:
break
print(*ans, sep = " ")
t = int(input())
for i in range(t):
solve()
蜜蜂