hdoj 2855 Fibonacci Check-up 【打表找规律 + 矩阵快速幂】

来源:互联网 发布:mac怎么启用flash 编辑:程序博客网 时间:2024/06/05 19:59



Fibonacci Check-up

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1268    Accepted Submission(s): 717


Problem Description
Every ALPC has his own alpc-number just like alpc12, alpc55, alpc62 etc.
As more and more fresh man join us. How to number them? And how to avoid their alpc-number conflicted? 
Of course, we can number them one by one, but that’s too bored! So ALPCs use another method called Fibonacci Check-up in spite of collision. 

First you should multiply all digit of your studying number to get a number n (maybe huge).
Then use Fibonacci Check-up!
Fibonacci sequence is well-known to everyone. People define Fibonacci sequence as follows: F(0) = 0, F(1) = 1. F(n) = F(n-1) + F(n-2), n>=2. It’s easy for us to calculate F(n) mod m. 
But in this method we make the problem has more challenge. We calculate the formula , is the combination number. The answer mod m (the total number of alpc team members) is just your alpc-number.
 

Input
First line is the testcase T.
Following T lines, each line is two integers n, m ( 0<= n <= 10^9, 1 <= m <= 30000 )
 

Output
Output the alpc-number.
 

Sample Input
21 300002 30000
 

Sample Output
13
 



题意说的很清楚了,就不多说了。



打表找规律——ans[n] = F[n*2],其中F[i]为斐波那契数列数列第i项。


附代码:


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int F[1001], C[1001];void getF(){    F[0] = 0, F[1] = 1;    for(int i = 2; i <= 100; i++)        F[i] = F[i-1] + F[i-2];}void solve(int n, int m){    int ans = 0;    C[0] = 1;    for(int i = 1; i <= n; i++)    {        C[i] = C[i-1] * (n-i+1) / i;        ans += C[i] * F[i] % m;    }    printf("%d\n", ans);}int main(){    getF();    int t;    int n, m;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &m);        solve(n, m);    }    return 0;}



找到规律后,直接矩阵KO。


AC代码:


#include <cstdio>#include <cstring>#include <algorithm>#define LL long longusing namespace std;struct Matrix{    LL a[2][2];};Matrix ori, res;LL F[2];void init_Matrix(){    memset(ori.a, 0, sizeof(ori.a));    memset(res.a, 0, sizeof(res.a));    res.a[0][0] = res.a[1][1] = 1;    ori.a[0][1] = ori.a[1][0] = ori.a[1][1] = 1;}Matrix muitl(Matrix x, Matrix y, int m){    Matrix z;    memset(z.a, 0, sizeof(z.a));    for(int i = 0; i < 2; i++)    {        for(int k = 0; k < 2; k++)        {            if(x.a[i][k] == 0) continue;            for(int j = 0; j < 2; j++)                z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j])%m) % m;        }    }    return z;}void solve(int n, int m){    init_Matrix();    while(n)    {        if(n & 1)            res = muitl(ori, res, m);        ori = muitl(ori, ori, m);        n >>= 1;    }    LL ans = res.a[1][1] % m;    printf("%lld\n", ans);}int main(){    F[0] = 0, F[1] = 1;    int t, n, m;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &m);        if(n == 0)        {            printf("0\n");            continue;        }        solve(n*2-1, m);    }    return 0;}


0 0