class poly():
@classmethod
def AddOrSub(cls, gx, fx, p, flag):
result = []
for i in range(max(len(gx), len(fx))):
tmp = 0
if i < len(gx):
tmp += gx[i]
if i < len(fx):
tmp += fx[i] * flag
tmp %= p
result.append(tmp)
return result
@classmethod
def Mul(cls, gx, fx, p):
result = [0]
for i in range(len(fx)):
tmp = [0] * i + [(j*fx[i])%p for j in gx]
result = cls.AddOrSub(result, tmp, p, 1)
return result
@classmethod
def Div(cls, gx, fx, p):
if len(gx)<len(fx):
return [0],gx
r = gx.copy()
index = len(r) - len(fx)
q = [0] * (index + 1)
while index >= 0:
q[index] = r[-1] // fx[-1]
tmp = cls.Mul(fx, [0] * index + [q[index]], p)
r = cls.AddOrSub(r, tmp, p, -1)
r = r[:firstNotZero(r)]
index = len(r) - len(fx)
return q, r
@classmethod
def polyInverse(cls, gx, fx, p):
g = gx.copy()
f = fx.copy()
xy = {'x-1':[1], 'x0':[0], 'y-1':[0], 'y0':[1]}
while len(f) > 0:
q, r = cls.Div(g, f, p)
g, f = f, r
x = cls.AddOrSub(xy['x-1'], cls.Mul(xy['x0'], q, p), p, -1)
y = cls.AddOrSub(xy['y-1'], cls.Mul(xy['y0'], q, p), p, -1)
xy['x-1'], xy['x0'] = xy['x0'], x[:firstNotZero(x)]
xy['y-1'], xy['y0'] = xy['y0'], y[:firstNotZero(y)]
return xy['x-1']
@classmethod
def MulMod(cls, ga, ha, fa, base):
return cls.Div(cls.Mul(ga, ha, base), fa, base)[1]
@classmethod
def PowerMod(ga, k, fa, base):
sa = [1];
while k > 0:
if k & 1 == 1:
sa = cls.MulMod(ga, sa, fa, base)
ga = cls.MulMod(ga, ga, fa, base)
k >>= 1
return sa
@classmethod
def ListToDec(cls, fa, base):
fa = fa[::-1]
result = 0
for i in fa:
result *= base
result += i
return result
@classmethod
def DecToList(cls, dec, base):
result = []
while dec > 0:
result.append(dec % base)
dec //= base
return result
@classmethod
def GenTable(cls, primitiveElement, fa, base):
newTable = [[], []]
newTable[0].append(1)
tableLen = base ** (len(fa) - 1)
newTable[1] = [0] * tableLen
a1 = cls.DecToList(primitiveElement, base)
ai = a1
for i in range(1, tableLen - 1):
newTable[0].append(cls.ListToDec(ai, base))
newTable[1][newTable[0][-1]] = i
ai = cls.MulMod(ai, a1, fa, base)
newTable[0].append(0)
newTable[1][0] = tableLen - 1
return newTable
def polyMulMod(ga, ha, fa, base):
return poly.MulMod(ga, ha, fa, base)
def polyInverseMod(ga, fa, base):
return poly.polyInverse(ga, fa, base)
def polyMulWithTable(ga, ha, table, base):
g = poly.ListToDec(ga, base)
h = poly.ListToDec(ha, base)
i_g = table[1][g]
i_h = table[1][h]
return poly.DecToList(table[0][(i_h + i_g + 1) % len(table[0])], base)
def polyInverseWithTable(ga, table, base):
g = poly.ListToDec(ga, base)
i_g = table[1][g]
g_inv = table[0][-1 - i_g]
return poly.DecToList(g_inv, base)
注意:输入和输出都是转置的列表