📅  最后修改于: 2023-12-03 15:12:38.362000             🧑  作者: Mango
本题考察了程序员的算法和数据结构的能力。
给定两个正整数 $p$ 和 $q$,定义 $G(p,q)$ 为Greatest Common Divisor(最大公约数),如下所定义:
$ G(p,q) = \begin{cases} p & \quad \text{if } q = 0 \ G(q,p % q) & \quad \text{otherwise} \ \end{cases} $
对于每个 $k$($1≤k≤n$),计算 $M_k=p^k+q^k$。
现在给定 $n$ 和 $S=p+q$,请计算 $\sum_{k=1}^n M_k$,其中 $M_k$ 满足 $M_k\equiv S\pmod{10^9+7}$。由于答案可能很大,请输出答案模 $10^9+7$ 的结果。
第一行包含一个正整数 $T$ 表示有 $T$ 组测试数据。对于每个测试数据,有一行,包含两个以空格分隔的整数 $n$ 和 $S$。
对于每个测试数据,输出一行,包含一个整数,表示 $\sum_{k=1}^n M_k\pmod {10^9+7}$ 的结果。
2
2 6
2 7
48
58
题目给定了两个正整数 $p$ 和 $q$,需要求出它们最大公约数,可以使用辗转相除法来实现。
为了方便起见,可以将 $p$ 和 $q$ 中的位数设为 $m$,在计算时,由于结果可能很大,需要对结果取模。在这里,取模数为 $10^9+7$,其可以进行快速幂运算。考虑到$p^k$ 可能特别大,不适合直接计算,所以我们使用快速幂来实现。
MOD_NUM = 10**9+7
# 快速幂算法,求 a 的 b 次方对 mod 取模的结果
def pow_mod(a: int, b: int, mod: int) -> int:
ans = 1
while b > 0:
if (b & 1) == 1:
ans = ans * a % mod
a = a * a % mod
b >>= 1
return ans
# 求 a 和 b 的最大公约数
def gcd(a: int, b: int) -> int:
if b == 0:
return a
return gcd(b, a%b)
# 求 p^k 对 mod 取模的结果
def pow_mod_p(p: int, k: int, mod: int) -> int:
return pow_mod(p, k, mod)
# 求 q^k 对 mod 取模的结果
def pow_mod_q(q: int, k: int, mod: int) -> int:
return pow_mod(q, k, mod)
# 求 S 的对模取余的值
def S_mod(p: int, q: int, mod: int) -> int:
ans = (p + q) % mod
return ans
# 求 p^k + q^k 对 mod 取模的结果
def pk_qk_mod(p: int, q: int, k: int, mod: int) -> int:
ans = pow_mod_p(p, k, mod) + pow_mod_q(q, k, mod)
ans %= mod
return ans
# 求 M_k 的值
def M_k(p: int, q: int, k: int, mod: int) -> int:
return pk_qk_mod(p, q, k, mod)
# 求与 S 同余的 M_k 的和
def M_k_S_mod_sum(n: int, p: int, q: int, S: int, mod: int) -> int:
ans = 0
for k in range(1, n+1):
if M_k(p, q, k, mod) % mod == S_mod(p, q, mod):
ans += M_k(p, q, k, mod)
ans %= mod
return ans
# 测试代码
data_count = int(input())
for i in range(data_count):
n, S = list(map(int, input().strip().split()))
p = gcd(n, S)
q = S - p
ans = M_k_S_mod_sum(n, p, q, S, MOD_NUM)
print(ans)
以上是本题的解题思路和代码实现,希望对大家有所帮助。