📜  门| GATE CS Mock 2018年|套装2 |第60章(1)

📅  最后修改于: 2023-12-03 15:12:38.362000             🧑  作者: Mango

GATE CS模拟试卷 2018年 - 套装2 - 第60题

本题考察了程序员的算法和数据结构的能力。

题目描述

给定两个正整数 $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
数据限制
  • $T≤10^4$
  • $1≤n≤10^9$
  • $1≤S≤10^9$
解题思路

题目给定了两个正整数 $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)

以上是本题的解题思路和代码实现,希望对大家有所帮助。