📅  最后修改于: 2023-12-03 15:11:33.188000             🧑  作者: Mango
这是一个涉及到数论和字符串操作的竞赛题目,需要熟练掌握大数和模运算相关算法。
给定两个正整数 $a$ 和 $b$,计算 $a^b$ 对 $10^{100}$ 取模后的结果。
两个正整数 $a$ 和 $b$,$1 \leq a, b \leq 10^{100}$。
一个字符串,即 $a^b$ 对 $10^{100}$ 取模后的结果。
2 5
0000000000000000000000000000000000000000000000000000000000000000032
首先需要注意到输入的两个数所代表的值的大小,无法使用标准的 int 或者 long 数据类型进行计算,因此需要使用字符串来表示。但是在进行模运算时,我们需要使用大数模板中封装了取模的操作来进行。
具体来说,我们可以使用快速幂算法来计算 $a^b$,在计算每一步的乘积时使用大数模板中提供的取模操作进行处理。需要注意的是,我们在计算幂时使用的是矩阵快速幂,相较于直接循环计算幂,这种方法可以更快地得出幂的结果。
使用 python
语言中的大数模板库来进行大数操作和取模:
# 大数模板
class BigNumber(str):
def __init__(self, x = 0):
if isinstance(x, str):
super().__init__()
else:
super().__init__(str(x))
def __str__(self):
return super().__str__()
def __int__(self):
return int(str(self))
def __repr__(self):
return self.__str__()
def mod(a: BigNumber, b: BigNumber) -> BigNumber:
r = 0
for c in str(a):
r *= 10
r += int(c)
r %= int(b)
return BigNumber(r)
在计算过程中,需要使用矩阵快速幂来较快地得出幂的结果。这里,我们封装了一个矩阵类,方便进行矩阵乘法计算:
# 矩阵类
class Matrix:
def __init__(self, data):
self.data = data
def __mul__(self, other):
if isinstance(other, Matrix):
res = [[0 for j in range(len(other.data[0]))] for i in range(len(self.data))]
for i in range(len(self.data)):
for j in range(len(other.data[0])):
for k in range(len(other.data)):
res[i][j] += self.data[i][k] * other.data[k][j]
return Matrix(res)
else:
return Matrix([i * other for i in self.data])
def __repr__(self):
s = ''
for i in range(len(self.data)):
s += '[%s]\n' % ' '.join(str(j) for j in self.data[i])
return s.strip()
使用快速幂计算矩阵 A 的 B 次幂,并将每一步结果取模再进行下一步计算:
# 快速幂计算
def powMod(A: Matrix, B: BigNumber, mod: BigNumber) -> Matrix:
res = Matrix([[(i == j) and 1 or 0 for j in range(len(A.data))] for i in range(len(A.data))])
while B != BigNumber(0):
if mod(B, 2) == BigNumber(1):
res = res * A
A = A * A
B = BigNumber(int(B) // 2)
for i in range(len(res.data)):
for j in range(len(res.data[i])):
res.data[i][j] = mod(BigNumber(res.data[i][j]), mod)
return res
# -*- coding: utf-8 -*-
# 大数模板
class BigNumber(str):
def __init__(self, x = 0):
if isinstance(x, str):
super().__init__()
else:
super().__init__(str(x))
def __str__(self):
return super().__str__()
def __int__(self):
return int(str(self))
def __repr__(self):
return self.__str__()
def mod(a: BigNumber, b: BigNumber) -> BigNumber:
r = 0
for c in str(a):
r *= 10
r += int(c)
r %= int(b)
return BigNumber(r)
# 矩阵类
class Matrix:
def __init__(self, data):
self.data = data
def __mul__(self, other):
if isinstance(other, Matrix):
res = [[0 for j in range(len(other.data[0]))] for i in range(len(self.data))]
for i in range(len(self.data)):
for j in range(len(other.data[0])):
for k in range(len(other.data)):
res[i][j] += self.data[i][k] * other.data[k][j]
return Matrix(res)
else:
return Matrix([i * other for i in self.data])
def __repr__(self):
s = ''
for i in range(len(self.data)):
s += '[%s]\n' % ' '.join(str(j) for j in self.data[i])
return s.strip()
# 快速幂计算
def powMod(A: Matrix, B: BigNumber, mod: BigNumber) -> Matrix:
res = Matrix([[(i == j) and 1 or 0 for j in range(len(A.data))] for i in range(len(A.data))])
while B != BigNumber(0):
if mod(B, 2) == BigNumber(1):
res = res * A
A = A * A
B = BigNumber(int(B) // 2)
for i in range(len(res.data)):
for j in range(len(res.data[i])):
res.data[i][j] = mod(BigNumber(res.data[i][j]), mod)
return res
a, b = input().split()
# 构造矩阵
A = Matrix([[0, 1], [1, 1]])
# 转化大数
a = BigNumber(a)
b = BigNumber(b)
# 矩阵快速幂
res = powMod(A, b, BigNumber(10) ** 100)
# 取模输出
print(str(res.data[0][1]).zfill(100))