結果
| 問題 | No.3414 Aperiodic Sequence |
| コンテスト | |
| ユーザー |
wolgnik
|
| 提出日時 | 2025-12-18 14:16:37 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,997 ms / 3,000 ms |
| コード長 | 4,260 bytes |
| 記録 | |
| コンパイル時間 | 303 ms |
| コンパイル使用メモリ | 82,908 KB |
| 実行使用メモリ | 203,712 KB |
| 最終ジャッジ日時 | 2025-12-20 23:31:31 |
| 合計ジャッジ時間 | 17,019 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
"""
lint
"""
import sys
def validate_input(raw: str):
# 入力末尾に余計な空行は無いか?
# → 最後の改行の後に空行があるとダメ
assert not raw.endswith('\n\n'), "末尾に余計な空行"
# 改行で入力が終わっているか?
assert raw.endswith('\n'), "改行で終わってない"
# 行末に余計なスペースは無いか?
lines = raw.rstrip('\n').split('\n')
for i, line in enumerate(lines):
assert line == line.rstrip(' '), f"{i+1}行目の末尾にスペースがある"
# 行頭にスペースがないか?
assert line == line.lstrip(' '), f"{i}行目:行頭にスペースがある"
# 連続スペースがないか?
assert ' ' not in line, f"{i}行目:連続スペースがある"
raw_input = sys.stdin.read()
validate_input(raw_input)
lines = raw_input.split('\n')
N, M = map(int, lines[0].split())
v = list(map(int, lines[1].split()))
mod = 998244353
class Convolution:
__slots__ = ['W', 'iW']
def __init__(self):
g = 3
ig = 332748118
self.W = [pow(g, (mod - 1) >> i, mod) for i in range(24)]
self.iW = [pow(ig, (mod - 1) >> i, mod) for i in range(24)]
def fmt(self, k, a):
W = self.W
for l in range(k, 0, -1):
d = 1 << (l - 1)
w = W[l]
for i in range(0, len(a), d * 2):
u = 1
for j in range(d):
s = i + j
a[s], a[s + d] = (a[s] + a[s + d]) % mod, u * (a[s] - a[s + d]) % mod
u = u * w % mod
return a
def ifmt(self, k, a):
iW = self.iW
for l in range(1, k + 1):
d = 1 << (l - 1)
w = iW[l]
for i in range(0, len(a), d * 2):
u = 1
for j in range(d):
s = i + j
a[s + d] *= u
a[s], a[s + d] = (a[s] + a[s + d]) % mod, (a[s] - a[s + d]) % mod
u = u * w % mod
return a
def Convolve(self, a, b):
n0 = len(a) + len(b) - 1
if n0 == 1:
return [a[0] * b[0] % mod]
if min(len(a), len(b)) <= 50:
res = [0] * n0
for i, ai in enumerate(a):
for j, bj in enumerate(b):
res[i + j] += ai * bj
return [x % mod for x in res]
k = n0.bit_length()
n = 1 << k
A = a + [0] * (n - len(a))
B = b + [0] * (n - len(b))
A = self.fmt(k, A)
B = self.fmt(k, B)
C = [A[i] * B[i] % mod for i in range(n)]
C = self.ifmt(k, C)
invn = pow(n, mod - 2, mod)
return [C[i] * invn % mod for i in range(n0)]
conv = Convolution()
def fps_inv(f, deg):
res = [pow(f[0], mod - 2, mod)]
d = 1
while d < deg:
d <<= 1
f_trunc = f[:min(len(f), d)]
fg = conv.Convolve(res, f_trunc)
ln = len(fg)
for i in range(ln):
fg[i] = -fg[i] % mod
fg += [0] * (d - ln)
fg[0] = (fg[0] + 2) % mod
res = conv.Convolve(res, fg)[:d]
return res[:deg]
def calc_g():
n = len(v)
if n == 0:
return [0] * (M + 1)
deg = M + 2
polys = [[1, -vi % mod] for vi in v]
while len(polys) > 1:
new_polys = []
for i in range(0, len(polys), 2):
if i + 1 < len(polys):
q_new = conv.Convolve(polys[i], polys[i + 1])
new_polys.append(q_new[:deg] if len(q_new) > deg else q_new)
else:
new_polys.append(polys[i])
polys = new_polys
Q = polys[0][:deg]
Q_deriv = [(k + 1) * Q[k + 1] % mod for k in range(len(Q) - 1)]
neg_Q_deriv = [-x % mod for x in Q_deriv]
Q_inv = fps_inv(Q, M + 1)
S = conv.Convolve(neg_Q_deriv, Q_inv)[:M + 1]
return [n] + S[:M]
g = calc_g()
# メビウス関数
mobius = [0] * (M + 1)
mobius[1] = 1
spf = list(range(M + 1))
for i in range(2, int(M ** 0.5) + 1):
if spf[i] == i:
for j in range(i * i, M + 1, i):
if spf[j] == j:
spf[j] = i
for i in range(2, M + 1):
p = spf[i]
prev = i // p
mobius[i] = 0 if prev % p == 0 else -mobius[prev]
# 約数
divisors = [[] for _ in range(M + 1)]
for i in range(1, M + 1):
for j in range(i, M + 1, i):
divisors[j].append(i)
# solve 展開
res = []
for n in range(1, M + 1):
f = 0
for d in divisors[n]:
m = mobius[n // d]
if m:
f = (f + m * pow(g[n // d], d, mod)) % mod
res.append(str(f))
print(' '.join(res))
wolgnik