HDU 1005 Number Sequence

Problem Description

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).

Input

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.

Output

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

Sample Input

1 1 3 1 2 10 0 0 0

Sample Output

2 5
 
题解:矩阵乘优化斐波那契的变形题,原本的公式是
        
   它实际上是
        
   每次进行一次
        
   这样的变换。
   在这道题中我们将变换稍微改变一下,变成每次
        
   
CODE:
#include <iostream>
#include <cstdio>
#include <cstring>
#define REP(i, s, n) for(int i = s; i <= n; i ++)
#define REP_(i, s, n) for(int i = n; i >= s; i --)
#define MAX_N 3
#define mod 7
using namespace std;

int a, b, n;
struct node{
    int Mtx[MAX_N][MAX_N];
}tmp, coe;

node operator+(node a,node b){
    node c;
    REP(i, 1, 2) REP(j, 1, 2){
        c.Mtx[i][j] = (a.Mtx[i][j] + b.Mtx[i][j]) % mod;
    }
    return c;
}

node operator*(node a,node b){
    node c;
    REP(i, 1, 2) REP(j, 1, 2){
        c.Mtx[i][j] = 0;
        REP(k, 1, 2) c.Mtx[i][j] = (c.Mtx[i][j] + a.Mtx[i][k] * b.Mtx[k][j]) % mod;
    }
    return c;
} 

node operator^(node a,int k){
    if(k == 0){
        memset(a.Mtx, 0, sizeof(a.Mtx));
        REP(i, 1, 2) a.Mtx[i][i] = 1;
        return a;
    }
    if(k == 1) return a;
    node c = a ^ (k >> 1);
    if(k & 1) return c * c * a;
    return c * c;
}
    
int main(){
    while(scanf("%d%d%d", &a, &b, &n) != EOF){
        if(a == 0 && b == 0 && n == 0) break;
        if(n == 1) { cout << 1 << endl; continue; }
        if(n == 2) { cout << 1 << endl; continue; }
        else {
            tmp.Mtx[1][1] = a * 1 + b * 1; tmp.Mtx[1][2] = 1; tmp.Mtx[2][1] = 1; tmp.Mtx[2][2] = 1;
            coe.Mtx[1][1] = a; coe.Mtx[1][2] = 1; coe.Mtx[2][1] = b; coe.Mtx[2][2] = 0;
            n -= 3; 
            coe = coe ^ n; tmp = tmp * coe;                
            cout << tmp.Mtx[1][1] << endl;
        }
    }
    return 0;
}
        

 

        
posted @ 2015-06-19 11:44  ALXPCUN  阅读(183)  评论(0编辑  收藏  举报