結果
| 問題 |
No.1018 suffixsuffixsuffix
|
| ユーザー |
|
| 提出日時 | 2021-05-09 12:38:33 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,981 bytes |
| コンパイル時間 | 746 ms |
| コンパイル使用メモリ | 81,948 KB |
| 実行使用メモリ | 98,112 KB |
| 最終ジャッジ日時 | 2024-09-18 18:49:20 |
| 合計ジャッジ時間 | 9,340 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 WA * 1 |
| other | AC * 14 WA * 20 |
ソースコード
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(2*10**5+10)
write = lambda x: sys.stdout.write(x+"\n")
debug = lambda x: sys.stderr.write(x+"\n")
writef = lambda x: print("{:.12f}".format(x))
def sa_naive(s):
n = len(s)
sa = list(range(n))
sa.sort(key=lambda x: s[x:])
return sa
def sa_doubling(s):
n = len(s)
sa = list(range(n))
rnk = s
tmp = [0] * n
k = 1
while k < n:
sa.sort(key=lambda x: (rnk[x], rnk[x + k])
if x + k < n else (rnk[x], -1))
tmp[sa[0]] = 0
for i in range(1, n):
tmp[sa[i]] = tmp[sa[i - 1]]
if sa[i - 1] + k < n:
x = (rnk[sa[i - 1]], rnk[sa[i - 1] + k])
else:
x = (rnk[sa[i - 1]], -1)
if sa[i] + k < n:
y = (rnk[sa[i]], rnk[sa[i] + k])
else:
y = (rnk[sa[i]], -1)
if x < y:
tmp[sa[i]] += 1
k *= 2
tmp, rnk = rnk, tmp
return sa
def sa_is(s, upper):
n = len(s)
if n == 0:
return []
if n == 1:
return [0]
if n == 2:
if s[0] < s[1]:
return [0, 1]
else:
return [1, 0]
if n < 10:
return sa_naive(s)
if n < 50:
return sa_doubling(s)
ls = [0] * n
for i in range(n-2, -1, -1):
ls[i] = ls[i + 1] if s[i] == s[i + 1] else s[i] < s[i + 1]
sum_l = [0] * (upper + 1)
sum_s = [0] * (upper + 1)
for i in range(n):
if ls[i]:
sum_l[s[i] + 1] += 1
else:
sum_s[s[i]] += 1
for i in range(upper):
sum_s[i] += sum_l[i]
if i < upper:
sum_l[i + 1] += sum_s[i]
lms_map = [-1] * (n + 1)
m = 0
for i in range(1, n):
if not ls[i - 1] and ls[i]:
lms_map[i] = m
m += 1
lms = []
for i in range(1, n):
if not ls[i - 1] and ls[i]:
lms.append(i)
sa = [-1] * n
buf = sum_s.copy()
for d in lms:
if d == n:
continue
sa[buf[s[d]]] = d
buf[s[d]] += 1
buf = sum_l.copy()
sa[buf[s[n - 1]]] = n - 1
buf[s[n - 1]] += 1
for i in range(n):
v = sa[i]
if v >= 1 and not ls[v - 1]:
sa[buf[s[v - 1]]] = v - 1
buf[s[v - 1]] += 1
buf = sum_l.copy()
for i in range(n-1, -1, -1):
v = sa[i]
if v >= 1 and ls[v - 1]:
buf[s[v - 1] + 1] -= 1
sa[buf[s[v - 1] + 1]] = v - 1
if m:
sorted_lms = []
for v in sa:
if lms_map[v] != -1:
sorted_lms.append(v)
rec_s = [0] * m
rec_upper = 0
rec_s[lms_map[sorted_lms[0]]] = 0
for i in range(1, m):
l = sorted_lms[i - 1]
r = sorted_lms[i]
end_l = lms[lms_map[l] + 1] if lms_map[l] + 1 < m else n
end_r = lms[lms_map[r] + 1] if lms_map[r] + 1 < m else n
same = True
if end_l - l != end_r - r:
same = False
else:
while l < end_l:
if s[l] != s[r]:
break
l += 1
r += 1
if l == n or s[l] != s[r]:
same = False
if not same:
rec_upper += 1
rec_s[lms_map[sorted_lms[i]]] = rec_upper
rec_sa = sa_is(rec_s, rec_upper)
for i in range(m):
sorted_lms[i] = lms[rec_sa[i]]
sa = [-1] * n
buf = sum_s.copy()
for d in sorted_lms:
if d == n:
continue
sa[buf[s[d]]] = d
buf[s[d]] += 1
buf = sum_l.copy()
sa[buf[s[n - 1]]] = n - 1
buf[s[n - 1]] += 1
for i in range(n):
v = sa[i]
if v >= 1 and not ls[v - 1]:
sa[buf[s[v - 1]]] = v - 1
buf[s[v - 1]] += 1
buf = sum_l.copy()
for i in range(n-1, -1, -1):
v = sa[i]
if v >= 1 and ls[v - 1]:
buf[s[v - 1] + 1] -= 1
sa[buf[s[v - 1] + 1]] = v - 1
return sa
def suffix_array(s, upper=255):
if type(s) is str:
s = [ord(c) for c in s]
return sa_is(s, upper)
def lcp_array(s, sa):
n = len(s)
rnk = [0] * n
for i in range(n):
rnk[sa[i]] = i
lcp = [0] * (n - 1)
h = 0
for i in range(n):
if h > 0:
h -= 1
if rnk[i] == 0:
continue
j = sa[rnk[i] - 1]
while j + h < n and i + h < n:
if s[j + h] != s[i + h]:
break
h += 1
lcp[rnk[i] - 1] = h
return lcp
n,m,q = list(map(int, input().split()))
s = input()
ks = list(map(int, input().split()))
sa = suffix_array(s)
ans = []
for k in ks:
val = sa[(k-1)//m] + n * (m-1-(k-1)%m) + 1
ans.append(val)
write(" ".join(map(str, ans)))