結果
| 問題 |
No.1839 Concatenation Matrix
|
| コンテスト | |
| ユーザー |
hitonanode
|
| 提出日時 | 2021-12-19 19:15:28 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,683 bytes |
| コンパイル時間 | 444 ms |
| コンパイル使用メモリ | 13,184 KB |
| 実行使用メモリ | 97,460 KB |
| 最終ジャッジ日時 | 2024-09-15 14:45:08 |
| 合計ジャッジ時間 | 14,990 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 8 TLE * 1 -- * 7 |
ソースコード
import numpy as np
class NTT:
def __init__(self, D: int, MOD: int, root: int) -> None:
self.md = MOD
self.w = np.array([1], np.int64)
self.iw = np.array([1], np.int64)
while len(self.w) < 1 << (D - 1):
dw = pow(root, (self.md - 1) // (len(self.w) * 4), self.md)
dwinv = pow(dw, -1, self.md)
self.w = np.r_[self.w, self.w * dw] % self.md
self.iw = np.r_[self.iw, self.iw * dwinv] % self.md
def ntt(self, mat: np.ndarray):
in_shape = mat.shape
n = in_shape[-1]
m = n // 2
while m:
mat = mat.reshape(-1, n // (m * 2), 2, m)
w_use = self.w[:n // (m * 2)].reshape(1, -1, 1)
y = mat[:, :, 1] * w_use % self.md
mat = np.stack((mat[:, :, 0] + y, mat[:, :, 0] + self.md - y), 2) % self.md
m //= 2
return mat.reshape(in_shape)
def intt(self, mat: np.ndarray):
in_shape = mat.shape
n = in_shape[-1]
m = 1
while m < n:
mat = mat.reshape(-1, n // (m * 2), 2, m)
iw_use = self.iw[:n // (m * 2)].reshape(1, -1, 1)
mat = np.stack((mat[:, :, 0] + mat[:, :, 1], (mat[:, :, 0] + self.md - mat[:, :, 1]) * iw_use), 2) % self.md
m *= 2
n_inv = pow(n, -1, self.md)
return mat.reshape(in_shape) * n_inv % self.md
def convolve(self, v1: np.ndarray, v2: np.ndarray) -> np.ndarray:
v1 = v1.copy()
v2 = v2.copy()
n1, n2 = len(v1), len(v2)
nret = n1 + n2 - 1
nfft = 1
while nfft < nret:
nfft <<= 1
v1.resize(nfft)
v2.resize(nfft)
v1 = self.ntt(v1)
v2 = self.ntt(v2)
vret = v1 * v2 % md
vret = self.intt(vret)
vret.resize(nret)
return vret
# https://maspypy.com/%E6%95%B0%E5%AD%A6%E3%83%BBnumpy-%E9%AB%98%E9%80%9F%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9Bfft%E3%81%AB%E3%82%88%E3%82%8B%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF
def convolve(f, g):
"""多項式 f, g の積を計算する。
Parameters
----------
f : np.ndarray (int64)
f[i] に、x^i の係数が入っている
g : np.ndarray (int64)
g[i] に、x^i の係数が入っている
Returns
-------
h : np.ndarray
f,g の積
"""
# h の長さ以上の n=2^k を計算
fft_len = 1
while 2 * fft_len < len(f) + len(g) - 1:
fft_len *= 2
fft_len *= 2
# フーリエ変換
Ff = np.fft.rfft(f, fft_len)
Fg = np.fft.rfft(g, fft_len)
# 各点積
Fh = Ff * Fg
# フーリエ逆変換
h = np.fft.irfft(Fh, fft_len)
# 小数になっているので、整数にまるめる
h = np.rint(h).astype(np.int64)
return h[:len(f) + len(g) - 1]
def convolve2(f, g, p):
f1, f2 = np.divmod(f, 1 << 15)
g1, g2 = np.divmod(g, 1 << 15)
a = convolve(f1, g1) % p
c = convolve(f2, g2) % p
b = (convolve(f1 + f2, g1 + g2) - (a + c)) % p
h = (a << 30) + (b << 15) + c
return h % p
md = 998244353
# convolver = NTT(18, md, 3)
N = int(input())
A = np.array(list(map(int, input().split())), dtype=np.int64)
polys = [None] * (N * 2)
p10 = 10
for i in range(N - 1):
polys[i] = np.array([1, p10], dtype=np.int64)
p10 = p10 * p10 % md
l, r = 0, N - 1
while l + 1 < r:
polys[r] = convolve2(polys[l], polys[l + 1], md)
polys[l] = None
polys[l + 1] = None
r += 1
l += 2
# vs = convolver.convolve(polys[l], A)
vs = convolve2(polys[l], A, md)
ret = np.zeros(N, dtype=np.int64)
for i, v in enumerate(vs):
ret[(i + 1) % N] += v
ret %= md
print(*ret, sep='\n')
hitonanode