SDUT1607:Number Sequence(矩阵快速幂)

题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1607

题目描述

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

题目解析:

模板题没什么好说的。

(f[1],f[2])*[ 0,1  ]=(f[2],f[3])

                [B, A ]

代码如下:

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
typedef long long  ll;
#define inf 0x3f3f3f3f
#define mod 7
#include <math.h>
#include <queue>
using namespace std;
struct ma
{
    ll a[2][2];
} init,res;
int A,B,n;
ma mult(ma x,ma y)
{
    ma tmp;
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            tmp.a[i][j]=0;
            for(int k=0; k<2; k++)
            {
                tmp.a[i][j]=(tmp.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
            }
        }
    }
    return tmp;
}
ma Pow(ma x,int K)
{
    ma tmp;
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            tmp.a[i][j]=(i==j);
        }
    }
    while(K)
    {
        if(K&1) tmp=mult(x,tmp);
        K>>=1;
        x=mult(x,x);
    }
    return tmp;
}
int main()
{
    while(scanf("%d%d%d",&A,&B,&n)!=EOF)
    {
        if(A==0&&B==0&&n==0) break;
        if(n==1||n==2)
        {
            printf("1\n");
            continue;
        }
        init.a[0][0]=0,init.a[0][1]=1;
        init.a[1][0]=B,init.a[1][1]=A;
        res=Pow(init,(n-1));
        ll sum=(res.a[0][0]+res.a[0][1])%mod;
        printf("%lld\n",sum);
    }
    return 0;
}

 

posted @ 2015-03-10 19:44  人艰不拆_zmc  阅读(198)  评论(0编辑  收藏  举报