Official
E - 円環文字列の辞書順ランキング / Lexicographic Ranking of Circular Strings Editorial
by
E - 円環文字列の辞書順ランキング / Lexicographic Ranking of Circular Strings Editorial
by
sounansya
各 \((x,l)\) に対し、\(C(x,l) > C(y,l)\) を満たす \(1\le y\le N\) の個数を求められれば良いです。
これは Trie 木を作ることで求めることができます。各 Trie 木のノードで現在そのノードまで同じ文字列がいくつあるか・そのノードが表す文字列と同じ長さの文字列で辞書順で真に小さい文字列がいくつあるか、を持ち計算することで全てまとめて \(\sigma = 26\) として \(O(\sigma N^2)\) で計算することができます。
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)
n, q = map(int, input().split())
s = input().rstrip()
s += s
d = [[-1] * n for _ in range(n)]
def f(l, offset, idxs):
if l == n:
return
if len(idxs) == 1:
i = idxs[0]
for j in range(l, n):
d[i][j] = offset
return
g = [[] for _ in range(26)]
for i in idxs:
g[ord(s[i + l]) - ord("a")].append(i)
for k in range(26):
if len(g[k]) == 0:
continue
for i in g[k]:
d[i][l] = offset
f(l + 1, offset, g[k])
offset += len(g[k])
f(0, 0, [i for i in range(n)])
for i in range(n):
for j in range(n - 1):
d[i][j + 1] += d[i][j]
idx = 0
for _ in range(q):
a, l = map(int, input().split())
idx = (idx + a) % n
print(d[idx][l - 1])
posted:
last update:
