【算法】小强爱数学(迭代公式+数论取模)

1. 问题

小强发现当已知 x y = B xy=B xy=B以及 x + y = A x+y=A x+y=A时,能很轻易的算出 x n x_ {n} xn + y n y_ {n} yn 的值.但小强想请你在已知A和B的情况下,计算出 x + y x+y x+y的值.因为这个结果可能很大所以所有的运算都在模1e9+7下进行.

2. 输入

第一行输入一个正整数T.表示有T组数据
接下来T行, 每行输入三个整数A,B和n
1 < = T < = 100 0 < = A , B < = 1 e 9 + 7 1 < = n < = 1 e 5 1<=T<=100\\ 0<=A,B<=1e9+7\\ 1<=n<=1e5 1<=T<=1000<=A,B<=1e9+71<=n<=1e5

3. 输出

输出 T T T行,每一行表示每组数据的结果.

4. 示例

输入例子:
3
4 4 3
2 3 4
5 2 6
输出例子:
16
999999993
9009

5. 分析

本题实际上就是个数学问题,积累了递推公式雀氏很好做,否则就很操蛋

递推公式

在这里插入图片描述

证明
在这里插入图片描述

6. 思路

迭代计算,类似斐波那契。不过需要小心溢出问题。本题中,A、B的值可能不会很大,但A、B计算处理后得到的值溢出的概率极高。如果A、B均为int,那么计算时就极容易发生溢出现象,因此A、B类型设置为long

此外,最终结果需要取模,笔者额外介绍一下数论中有关取模的信息

7. 数论,取模相关公式

(a + b) % p = (a%p + b%p) %p
(a - b) % p = ((a%p - b%p) + p) %p
(a * b) % p = (a%p)*(b%p) %p

详细介绍的文章

快速求模,其实就是运用到了取模的性质,把大的数字分部拆解为小的数字。当然拆的过程中会出现各种细节

一句话总结:拆出来的数字,都取模。切记除法、指数不要这么做


8. 数论,同余定理

如果(a - b)能够被m整除,即m | (a - b),那么a mod m = b mod m。我们称称整数a与b对模m同余,记作a≡b(mod m)

这个也好理解,a - b能够被m整除,说明a,和b mod m能够得到相同余数,只有这样,a - b才能把多余的数字去除,因此a - b才能被m整除

详细介绍的文章

9. 代码

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static final int mod = 1000000000 + 7;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt(), n;
        long A, B; 
        for (int i = 0; i < T; ++i) {
            A = sc.nextInt(); B = sc.nextInt(); n = sc.nextInt();
            long[] dp = new long[n + 1];
            dp[1] = A % mod; 
            // 为了防止溢出,注意取模。具体公式上文有讲
            dp[2] = (A * A % mod - 2 * B % mod + mod) % mod;
            if (n == 1) {
                System.out.println(dp[1]);
            }else if (n == 2) {
                System.out.println(dp[2]);
            }else {
                for (int j = 3; j <= n; ++j) {
                    dp[j] = (A * dp[j - 1] % mod - B * dp[j - 2] % mod + mod) % mod;
                }
                System.out.println(dp[n]);
            }
        }
    }
}

在这里插入图片描述

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值