This documentation is automatically generated by online-judge-tools/verification-helper
import cp_library.__header__
import cp_library.math.__header__
import cp_library.math.conv.__header__
from cp_library.math.conv.ior_zeta_pair_fn import ior_zeta_pair
from cp_library.math.conv.ior_mobius_fn import ior_mobius
def ior_conv(A: list[int], B: list[int], N: int, mod: int) -> list[int]:
assert len(A) == len(B)
Z = 1 << N
ior_zeta_pair(A, B, N)
for i, b in enumerate(B): A[i] = A[i]*b%mod
ior_mobius(A, N)
for i, a in enumerate(Z): A[i] = a%mod
return A
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
https://kobejean.github.io/cp-library
'''
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
x₀ ────────●─●────────●───●────────●───────●────────► X₀
╳ ╲ ╱ ╲ ╱
x₄ ────────●─●────────●─╳─●────────●─╲───╱─●────────► X₁
╳ ╳ ╲ ╲ ╱ ╱
x₂ ────────●─●────────●─╳─●────────●─╲─╳─╱─●────────► X₂
╳ ╱ ╲ ╲ ╳ ╳ ╱
x₆ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₃
╳ ╳ ╳ ╳
x₁ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₄
╳ ╲ ╱ ╱ ╳ ╳ ╲
x₅ ────────●─●────────●─╳─●────────●─╱─╳─╲─●────────► X₅
╳ ╳ ╱ ╱ ╲ ╲
x₃ ────────●─●────────●─╳─●────────●─╱───╲─●────────► X₆
╳ ╱ ╲ ╱ ╲
x₇ ────────●─●────────●───●────────●───────●────────► X₇
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
Math - Convolution
'''
def ior_zeta_pair(A: list[int], B: list[int], N: int, Z: int = None):
Z = Z if Z else len(A)
for i in range(N):
m = b = 1<<i
while m < Z: A[m] += A[m^b]; B[m] += B[m^b]; m = m+1|b
return A, B
def ior_mobius(A: list[int], N: int, Z: int = None):
Z = Z if Z else len(A)
for i in range(N):
m = b = 1<<i
while m < Z: A[m] -= A[m^b]; m = m+1|b
return A
def ior_conv(A: list[int], B: list[int], N: int, mod: int) -> list[int]:
assert len(A) == len(B)
Z = 1 << N
ior_zeta_pair(A, B, N)
for i, b in enumerate(B): A[i] = A[i]*b%mod
ior_mobius(A, N)
for i, a in enumerate(Z): A[i] = a%mod
return A