This documentation is automatically generated by online-judge-tools/verification-helper
import cp_library.__header__
import cp_library.math.__header__
from cp_library.math.conv.subset_deconv_fn import subset_deconv
import cp_library.math.sps.__header__
def sps_div(A, B): return subset_deconv(A, B, len(A).bit_length()-1)
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
https://kobejean.github.io/cp-library
'''
def popcnts(N):
P = [0]*(1 << N)
for i in range(N):
for m in range(b := 1<<i):
P[m^b] = P[m] + 1
return P
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
x₀ ────────●─●────────●───●────────●───────●────────► X₀
╳ ╲ ╱ ╲ ╱
x₄ ────────●─●────────●─╳─●────────●─╲───╱─●────────► X₁
╳ ╳ ╲ ╲ ╱ ╱
x₂ ────────●─●────────●─╳─●────────●─╲─╳─╱─●────────► X₂
╳ ╱ ╲ ╲ ╳ ╳ ╱
x₆ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₃
╳ ╳ ╳ ╳
x₁ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₄
╳ ╲ ╱ ╱ ╳ ╳ ╲
x₅ ────────●─●────────●─╳─●────────●─╱─╳─╲─●────────► X₅
╳ ╳ ╱ ╱ ╲ ╲
x₃ ────────●─●────────●─╳─●────────●─╱───╲─●────────► X₆
╳ ╱ ╲ ╱ ╲
x₇ ────────●─●────────●───●────────●───────●────────► X₇
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
Math - Convolution
'''
def ior_zeta_pair_ranked(A, B, N, M, Z):
for i in range(0, Z, M):
l, r = i+(1<<(i>>N))-1, i+M
for j in range(N):
m = l|(b := 1<<j)
while m < r: A[m] += A[m^b]; B[m] += B[m^b]; m = m+1|b
return A, B
def ior_mobius_ranked(A: list[int], N: int, M: int, Z: int):
for i in range(0, Z, M):
l, r = i, i+M-(1<<(N-(i>>N)))+1
for j in range(N):
m = l|(b := 1<<j)
while m < r: A[m] -= A[m^b]; m = m+1|b
return A
def isubset_deconv_ranked(Ar, Br, N, Z, M):
inv = 1 // Br[0]; ior_zeta_pair_ranked(Ar, Br, N, M, Z)
for i in range(0, Z, M):
for k in range(M): Ar[i|k] *= inv
for j in range(M, Z-i, M):
ij = i + j; l = (1 << (j>>N))-1
for k in range(l, M): Ar[ij|k] -= Ar[i|k] * Br[j|k]
return ior_mobius_ranked(Ar, N, M, Z)
def subset_deconv(A: list[int], B: list[int], N: int) -> list[int]:
Z = (N+1)*(M:=1<<N)
Ar, Br, C, P = [0]*Z, [0]*Z, [0]*M, popcnts(N)
for i, p in enumerate(P): Ar[p<<N|i], Br[p<<N|i] = A[i], B[i]
isubset_deconv_ranked(Ar, Br, N, Z, M)
for i, p in enumerate(P): C[i] = Ar[p<<N|i]
return C
def sps_div(A, B): return subset_deconv(A, B, len(A).bit_length()-1)