def firstNotZero(array):
for i in range(len(array) - 1, -1, -1):
if array[i] > 0:
return i + 1
return 0
def multiPreSqu(base, num):
if type(num) is str:
num = num[::-1]
num = list(map(int, num))
t = len(num)
w = [0] * (2 * t)
for i in range(t):
uv = w[2 * i] + num[i]**2
w[2 * i] = uv % base
carry = uv // base
for j in range(i + 1, t):
uv = w[i + j] + 2 * num[j] * num[i] + carry
w[i + j] = uv % base
carry = uv // base
w[i + t] = carry
return w
def multiPreGreaterEqual(num1, num2):
if type(num1) is str:
num1 = list(map(int, num1))
else:
num1 = num1[::-1]
num1 = num1[len(num1) - firstNotZero(num1[::-1]):]
if type(num2) is str:
num2 = list(map(int, num2))
else:
num2 = num2[::-1]
num2 = num2[len(num2) - firstNotZero(num2[::-1]):]
if len(num1) > len(num2):
return True
if len(num1) < len(num2):
return False
for i in range(len(num1)):
if num1[i] > num2[i]:
return True
if num1[i] < num2[i]:
return False
return True
def multiPreAdd(base, num1, num2):
if type(num1) is str:
num1 = num1[::-1]
num1 = list(map(int, num1))
if type(num2) is str:
num2 = num2[::-1]
num2 = list(map(int, num2))
result = []
carry = 0
for i in range(max(len(num1), len(num2))):
tmp = carry
if i < len(num1):
tmp += num1[i]
if i < len(num2):
tmp += num2[i]
carry = tmp // base
tmp %= base
result.append(tmp)
if carry > 0:
result.append(carry % base)
return result
def multiPreSub(base, num1, num2):
if type(num1) is str:
num1 = num1[::-1]
num1 = list(map(int, num1))
if type(num2) is str:
num2 = num2[::-1]
num2 = list(map(int, num2))
result = []
borrow = 0
for i in range(len(num1)):
tmp = num1[i] + borrow
if(i < len(num2)):
tmp -= num2[i]
borrow = -1 if tmp < 0 else 0
tmp += -1 * borrow * base
result.append(tmp)
return result
def multiPreMul(base, num1, num2):
if type(num1) is str:
num1 = num1[::-1]
num1 = list(map(int, num1))
if type(num2) is str:
num2 = num2[::-1]
num2 = list(map(int, num2))
n = len(num1) - 1
t = len(num2) - 1
w = [0] * (n + t + 2)
for i in range(t + 1):
carry = 0
for j in range(n + 1):
uv = w[i + j] + num1[j] * num2[i] + carry
w[i + j] = uv % base
carry = uv // base
w[i + n + 1] = carry
return w
def multiPreDiv(base, x, y):
if type(x) is str:
x = x[::-1]
x = list(map(int, x))
if type(y) is str:
y = y[::-1]
y = list(map(int, y))
n = len(x) - 1
t = len(y) - 1
q = [0] * (n - t + 1)
while multiPreGreaterEqual(x, [0] * (n - t) + y):
q[n - t] += 1
x = multiPreSub(base, x, [0] * (n - t) + y)
for i in range(n, t, -1):
if x[i] == y[t]:
q[i - t - 1] = base - 1
else:
q[i - t - 1] = (x[i] * base + x[i - 1]) // y[t]
judge = x[i] * base * base + x[i - 1] * base + x[i - 2]
while q[i - t - 1] * (y[t] * base + y[t - 1]) > judge:
q[i - t - 1] -= 1
judge = multiPreMul(base, [q[i - t - 1]], [0] * (i - t - 1) + y)
if not multiPreGreaterEqual(x, judge):
x = multiPreAdd(base, x, [0] * (i - t - 1) + y)
q[i - t - 1] -= 1
x = multiPreSub(base, x, judge)
return q[:firstNotZero(q)], x[:firstNotZero(x)]
注意,传入的可以是正序的字符串和逆序的列表,传出的是逆序的列表