結果
問題 | No.1307 Rotate and Accumulate |
ユーザー | 👑 rin204 |
提出日時 | 2022-11-08 18:12:46 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 216 ms / 5,000 ms |
コード長 | 6,901 bytes |
コンパイル時間 | 946 ms |
コンパイル使用メモリ | 82,660 KB |
実行使用メモリ | 117,024 KB |
最終ジャッジ日時 | 2024-07-22 02:20:26 |
合計ジャッジ時間 | 4,909 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 40 ms
54,036 KB |
testcase_01 | AC | 42 ms
53,840 KB |
testcase_02 | AC | 41 ms
54,248 KB |
testcase_03 | AC | 44 ms
59,792 KB |
testcase_04 | AC | 43 ms
54,168 KB |
testcase_05 | AC | 42 ms
54,372 KB |
testcase_06 | AC | 44 ms
58,896 KB |
testcase_07 | AC | 40 ms
54,040 KB |
testcase_08 | AC | 173 ms
99,940 KB |
testcase_09 | AC | 178 ms
102,196 KB |
testcase_10 | AC | 162 ms
99,224 KB |
testcase_11 | AC | 144 ms
90,308 KB |
testcase_12 | AC | 163 ms
108,656 KB |
testcase_13 | AC | 103 ms
88,068 KB |
testcase_14 | AC | 118 ms
89,928 KB |
testcase_15 | AC | 215 ms
116,352 KB |
testcase_16 | AC | 216 ms
116,368 KB |
testcase_17 | AC | 216 ms
116,104 KB |
testcase_18 | AC | 208 ms
110,888 KB |
testcase_19 | AC | 214 ms
116,104 KB |
testcase_20 | AC | 213 ms
117,024 KB |
testcase_21 | AC | 40 ms
53,976 KB |
ソースコード
class FFT: def __init__(self, MOD=998244353): FFT.MOD = MOD self.make_info(MOD) def make_info(self, MOD): g = self.primitive_root_constexpr() m = MOD - 1 rank2 = (m & -m).bit_length() - 1 root = [0] * (rank2 + 1) iroot = [0] * (rank2 + 1) rate2 = [0] * (rank2 + 1) irate2 = [0] * (rank2 + 1) rate3 = [0] * (rank2) irate3 = [0] * (rank2) root[rank2] = pow(g, (MOD - 1) >> rank2, MOD) iroot[rank2] = pow(root[rank2], MOD - 2, MOD) for i in range(rank2 - 1, -1, -1): root[i] = root[i + 1] * root[i + 1] % MOD iroot[i] = iroot[i + 1] * iroot[i + 1] % MOD prod = 1 iprod = 1 for i in range(1, rank2): rate2[i] = root[i + 1] * prod % MOD irate2[i] = iroot[i + 1] * iprod % MOD prod = prod * iroot[i + 1] % MOD iprod = iprod * root[i + 1] % MOD prod = 1 iprod = 1 for i in range(1, rank2 - 1): rate3[i] = root[i + 2] * prod % MOD irate3[i] = iroot[i + 2] * iprod % MOD prod = prod * iroot[i + 2] % MOD iprod = iprod * root[i + 2] % MOD self.IMAG = rate2[1] self.IIMAG = irate2[1] self.rate2 = rate2 self.irate2 = irate2 self.rate3 = rate3 self.irate3 = irate3 def primitive_root_constexpr(self): if FFT.MOD == 998244353: return 3 elif FFT.MOD == 200003: return 2 elif FFT.MOD == 167772161: return 3 elif FFT.MOD == 469762049: return 3 elif FFT.MOD == 754974721: return 11 divs = [0] * 20 divs[0] = 2 cnt = 1 x = (FFT.MOD - 1) // 2 while x % 2 == 0: x //= 2 i = 3 while i * i <= x: if x % i == 0: divs[cnt] = i cnt += 1 while x % i == 0: x //= i i += 2 if x > 1: divs[cnt] = x cnt += 1 g = 2 while 1: ok = True for i in range(cnt): if pow(g, (FFT.MOD - 1) // divs[i], FFT.MOD) == 1: ok = False break if ok: return g g += 1 def butterfly(self, A): n = len(A) h = (n - 1).bit_length() le = 0 while le < h: if h - le == 1: p = 1 << (h - le - 1) rot = 1 for s in range(1 << le): offset = s << (h - le) for i in range(p): l = A[i + offset] r = A[i + offset + p] * rot A[i + offset] = (l + r) % FFT.MOD A[i + offset + p] = (l - r) % FFT.MOD rot *= self.rate2[(~s & -~s).bit_length()] rot %= FFT.MOD le += 1 else: p = 1 << (h - le - 2) rot = 1 for s in range(1 << le): rot2 = rot * rot % FFT.MOD rot3 = rot2 * rot % FFT.MOD offset = s << (h - le) for i in range(p): a0 = A[i + offset] a1 = A[i + offset + p] * rot a2 = A[i + offset + p * 2] * rot2 a3 = A[i + offset + p * 3] * rot3 a1na3imag = (a1 - a3) % FFT.MOD * self.IMAG A[i + offset] = (a0 + a2 + a1 + a3) % FFT.MOD A[i + offset + p] = (a0 + a2 - a1 - a3) % FFT.MOD A[i + offset + p * 2] = (a0 - a2 + a1na3imag) % FFT.MOD A[i + offset + p * 3] = (a0 - a2 - a1na3imag) % FFT.MOD rot *= self.rate3[(~s & -~s).bit_length()] rot %= FFT.MOD le += 2 def butterfly_inv(self, A): n = len(A) h = (n - 1).bit_length() le = h while le: if le == 1: p = 1 << (h - le) irot = 1 for s in range(1 << (le - 1)): offset = s << (h - le + 1) for i in range(p): l = A[i + offset] r = A[i + offset + p] A[i + offset] = (l + r) % FFT.MOD A[i + offset + p] = (l - r) * irot % FFT.MOD irot *= self.irate2[(~s & -~s).bit_length()] irot %= FFT.MOD le -= 1 else: p = 1 << (h - le) irot = 1 for s in range(1 << (le - 2)): irot2 = irot * irot % FFT.MOD irot3 = irot2 * irot % FFT.MOD offset = s << (h - le + 2) for i in range(p): a0 = A[i + offset] a1 = A[i + offset + p] a2 = A[i + offset + p * 2] a3 = A[i + offset + p * 3] a2na3iimag = (a2 - a3) * self.IIMAG % FFT.MOD A[i + offset] = (a0 + a1 + a2 + a3) % FFT.MOD A[i + offset + p] = (a0 - a1 + a2na3iimag) * irot % FFT.MOD A[i + offset + p * 2] = (a0 + a1 - a2 - a3) * irot2 % FFT.MOD A[i + offset + p * 3] = (a0 - a1 - a2na3iimag) * irot3 % FFT.MOD irot *= self.irate3[(~s & -~s).bit_length()] irot %= FFT.MOD le -= 2 def convolve(self, A, B): n = len(A) m = len(B) if min(n, m) <= 60: C = [0] * (n + m - 1) for i in range(n): if i % 8 == 0: for j in range(m): C[i + j] += A[i] * B[j] C[i + j] %= FFT.MOD else: for j in range(m): C[i + j] += A[i] * B[j] return [c % FFT.MOD for c in C] A = A[:] B = B[:] z = 1 << (n + m - 2).bit_length() A += [0] * (z - n) B += [0] * (z - m) self.butterfly(A) self.butterfly(B) for i in range(z): A[i] *= B[i] A[i] %= FFT.MOD self.butterfly_inv(A) A = A[:n + m - 1] iz = pow(z, FFT.MOD - 2, FFT.MOD) return [a * iz % FFT.MOD for a in A] n, Q = map(int, input().split()) A = list(map(int, input().split())) R = list(map(int, input().split())) B = [0] * n for r in R: B[-r] += 1 fft = FFT() A = fft.convolve(A, B) for i in range(n, len(A)): A[i - n] += A[i] print(*A[:n])