結果

問題 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
権限があれば一括ダウンロードができます

ソースコード

diff #

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()
0