Number Sequence HDU1005

题目:

A number sequence is defined as follows: 

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 

Given A, B, and n, you are to calculate the value of f(n). 

输入:

The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed. 

输出:

For each test case, print the value of f(n) on a single line. 

样例输入:

1 1 3
1 2 10
0 0 0

样例输出:

2
5

 

这道题杭电上的数据比较水,很多人通过找规律就过了(以48或49为周期去找规律),但其实这样不对,下面几组数据就过不去

247 602 35363857
376 392 9671521
759 623 18545473
53 399 46626337
316 880 10470347
0 0 0

Output:
4
3
5
2
3

正确的做法应该是用矩阵快速幂。

题目中的递推式可化为下面的矩阵等式

\begin{bmatrix} f(3)\\f(2) \end{bmatrix}=\begin{bmatrix} a &b \\1 & 0 \end{bmatrix} \begin{bmatrix} f(2) \\f(1) \end{bmatrix}

\begin{bmatrix} f(4)\\f(3) \end{bmatrix}=\begin{bmatrix} a &b \\1 & 0 \end{bmatrix} \begin{bmatrix} f(3) \\f(2) \end{bmatrix}

\begin{bmatrix} f(4)\\f(3) \end{bmatrix}=\begin{bmatrix} a &b \\1 & 0 \end{bmatrix}\begin{bmatrix} a &b \\1 & 0 \end{bmatrix} \begin{bmatrix} f(2) \\f(1) \end{bmatrix}

......

\begin{bmatrix} f(n)\\f(n-1) \end{bmatrix}=\begin{bmatrix} a &b \\1 & 0 \end{bmatrix} ^{n-2} \begin{bmatrix} f(2) \\f(1) \end{bmatrix}

接下来主要就是求  \begin{bmatrix} a &b \\1 & 0 \end{bmatrix} ^{n-2}了,可以用到快速幂的方法。

以下代码也可做矩阵快速幂的模板参考。

#include <iostream>

using namespace std;
struct Matrix//用结构体方便处理
{
    int f[2][2];
};
Matrix e;
Matrix Mul(Matrix a,Matrix b)//矩阵相乘
{
    Matrix temp;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        temp.f[i][j]=0;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        for(int k=0;k<2;k++)
        temp.f[i][j]=(temp.f[i][j]+a.f[i][k]*b.f[k][j]%7)%7;
    return temp;
}
Matrix pow(Matrix x,long long n)//快速幂
{
    while(n)
    {
        if(n&1) e=Mul(e,x);
        x=Mul(x,x);
        n>>=1;
    }
    return e;
}
int main()
{
    int a,b,n;
    while(cin>>a>>b>>n&&a!=0&&b!=0&&n!=0)
    {
        if(n<=2){cout<<"1\n";continue;}
        e.f[0][0]=e.f[1][1]=1;
        e.f[0][1]=e.f[1][0]=0;//快速幂初始化
        Matrix x,ans;
        x.f[0][0]=a;x.f[0][1]=b;
        x.f[1][0]=1;x.f[1][1]=0;
        ans=pow(x,n-2);
        cout<<(ans.f[0][0]+ans.f[0][1])%7<<"\n";
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值