結果
| 問題 |
No.2454 Former < Latter
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-09-01 23:32:34 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 929 ms / 2,000 ms |
| コード長 | 4,282 bytes |
| コンパイル時間 | 275 ms |
| コンパイル使用メモリ | 82,164 KB |
| 実行使用メモリ | 123,844 KB |
| 最終ジャッジ日時 | 2025-01-03 12:41:09 |
| 合計ジャッジ時間 | 7,519 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 23 |
ソースコード
import sys
input = lambda :sys.stdin.readline()[:-1]
ni = lambda :int(input())
na = lambda :list(map(int,input().split()))
yes = lambda :print("yes");Yes = lambda :print("Yes");YES = lambda : print("YES")
no = lambda :print("no");No = lambda :print("No");NO = lambda : print("NO")
#######################################################################
def SA_IS(a):
a += [0]
k = max(a) + 1
n = len(a)
def induce_l(sa, a, n, k, stype):
bucket = get_buckets(a, k, 1)
for i in range(n):
j = sa[i] - 1
if j >= 0 and (not stype[j]):
sa[bucket[a[j]]] = j
bucket[a[j]] += 1
def induce_s(sa, a, n, k, stype):
bucket = get_buckets(a, k, 0)
for i in range(n)[::-1]:
j = sa[i] - 1
if j >= 0 and stype[j]:
bucket[a[j]] -= 1
sa[bucket[a[j]]] = j
def get_buckets(a, k, start = 0):
bucket = [0] * k
for item in a:
bucket[item] += 1
s = 0
for i in range(k):
s += bucket[i]
bucket[i] = s - (bucket[i] if start else 0)
return bucket
def set_lms(a, n, k, default_order):
bucket = get_buckets(a, k)
sa = [-1] * n
for i in default_order[::-1]:
bucket[a[i]] -= 1
sa[bucket[a[i]]] = i
return sa
def induce(a, n, k, stype, default_order):
sa = set_lms(a, n, k, default_order)
induce_l(sa, a, n, k, stype)
induce_s(sa, a, n, k, stype)
return sa
def rename_LMS_substring(sa, a, n, stype, LMS, l):
sa = [_s for _s in sa if LMS[_s]]
tmp = [-1] * (n//2) + [0]
dupl = 0
for _ in range(1, l):
i, j = sa[_-1], sa[_]
for ii in range(n):
if a[i+ii] != a[j+ii] or stype[i+ii] != stype[j+ii]:
break
if ii and (LMS[i+ii] or LMS[j+ii]):
dupl += 1
break
tmp[j//2] = _ - dupl
tmp = [t for t in tmp if t >= 0]
return tmp, dupl
def calc(a, n, k):
stype = [1] * n
for i in range(n-1)[::-1]:
if a[i] > a[i+1] or (a[i] == a[i+1] and stype[i+1] == 0):
stype[i] = 0
LMS = [1 if stype[i] and not stype[i-1] else 0 for i in range(n-1)] + [1]
l = sum(LMS)
lms = [i for i in range(n) if LMS[i]]
sa = induce(a, n, k, stype, lms)
renamed_LMS, dupl = rename_LMS_substring(sa, a, n, stype, LMS, l)
if dupl:
sub_sa = calc(renamed_LMS, l, l - dupl)
else:
sub_sa = [0] * l
for i in range(l):
sub_sa[renamed_LMS[i]] = i
lms = [lms[sub_sa[i]] for i in range(l)]
sa = induce(a, n, k, stype, lms)
return sa
sa = calc(a, n, k)
return sa
# Longest Common Prefix
# (文字列s, 文字列長n, Suffix Array)を引数として与える
def LCP(s, n, sa):
lcp = [-1]*(n+1)
rank = [0]*(n+1)
for i in range(n+1): rank[sa[i]] = i
h = 0
lcp[0] = 0
for i in range(n):
j = sa[rank[i] - 1]
if h > 0: h -= 1
while j+h < n and i+h < n and s[j+h]==s[i+h]:
h += 1
lcp[rank[i] - 1] = h
return lcp
for _ in range(ni()):
n = ni()
S = [ord(a)-96 for a in input()]
SSA = SA_IS(S)
ans = 0
c = 0
SA = list(SSA[1:])
#print(SA)
lcp = LCP(S, n, SSA)
j = SA.index(0)
a = [n+1] * n
a[j] = n
for i in range(j+1, n):
a[i] = min(a[i-1], lcp[i])
for i in range(j-1,-1,-1):
a[i] = min(a[i+1], lcp[i+1])
#print(j,lcp,a)
b = []
for i in range(n):
l = min(n-SA[i], SA[i])
if SA[i] == 0:
c = 1
continue
#print(SA[i], l, a[i])
if a[i] < l:
ans += c
if c == 1:
b.append(SA[i])
else:
if n - SA[i] > SA[i]:
ans += 1
b.append(SA[i])
print(ans)
"""print(sorted(b))
z = 0
for i in range(1,n):
if S[i:] > S[:i]:
print(S[:i], S[i:])
z += 1
print(z)"""