Fibonacci Check-up

Fibonacci Check-up

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 42 Accepted Submission(s): 27
 
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
2
1 30000
2 30000
 
Sample Output
1
3
 
 
Source
2009 Multi-University Training Contest 5 - Host by NUDT
 
Recommend
gaojie
 
/*
题意:给出你公式,让你求( 求和C(k,n)F(k) )%m

初步思路:没思路,先打表
            得到:
            0
            1
            3
            8
            21
            55
            144
            377
            987
            2584
            6765
            17711
            46368
            121393
            317811
            832040
            2178309
            5702887
            14930352
            39088169
            102334155
            能得出来,G(0)=0;
                      G(1)=1;
                      G(n)=3*G(n-1)-G(n-2);
            然后用矩阵快速幂求出结果
            
            最重要的构造矩阵还没学线性代数的我只能试着推出来:
            |G(n) G(n-1)| | 3     1   |
            | 0    0    |*| -1    0   |

#总结:板没调好,WA了两发
            
*/
#include<bits/stdc++.h>
using namespace std;
int n,mod;
int t;
/********************************矩阵模板**********************************/
class Matrix {
    public:
        int a[3][3];
        int n;  

        void init(int x) {
            memset(a,0,sizeof(a));
            if(x){
                a[0][0]=3;
                a[0][1]=1;
                a[1][0]=-1;
                a[1][1]=0;
            }else{
                a[0][0]=1;
                a[0][1]=0;
                a[1][0]=0;
                a[1][1]=0;
            }
            n=2;
        }

        Matrix operator +(Matrix b) {
            Matrix c;
            c.n = n;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    c.a[i][j] = (a[i][j] + b.a[i][j]) % mod;
            return c;
        }

        Matrix operator +(int x) {
            Matrix c = *this;
            for (int i = 0; i < n; i++)
                c.a[i][i] += x;
            return c;
        }

        Matrix operator *(Matrix b)
        {
            Matrix p;
            p.n = b.n;   
            memset(p.a,0,sizeof p.a);
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                for (int k = 0; k < n; k++)
                    p.a[i][j] = (p.a[i][j] + (a[i][k]*b.a[k][j])%mod) % mod;
            return p;
        }

        Matrix power_1(int t) {
            Matrix ans,p = *this;
            ans = p;
            while (t) {
                if (t & 1)
                    ans=ans*p;
                p = p*p;
                t >>= 1;
            }
            return ans;
        }
        
        Matrix power_2(Matrix a,Matrix b,int x){
            while(x){
                if(x&1){
                    b=a*b;
                }
                a=a*a;
                x>>=1;
            }
            return b;
        }
};
/********************************矩阵模板**********************************/
Matrix unit,init;
int main(){
    // freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&mod);
        unit.init(0);//存放G(n)的矩阵
        init.init(1);//子矩阵
        if(n==0){
            printf("0\n");
            continue;
        }else if(n==1){
            printf("%d\n",1%mod);
            continue;
        }
        init=init.power_1(n-2);
        unit=unit*init;
        // cout<<mod<<endl;
        // for(int i=0;i<2;i++){
            // for(int j=0;j<2;j++){
                // cout<<init.a[i][j]<<" ";
            // }
            // cout<<endl;
        // }
        
        printf("%d\n",(unit.a[0][0]+mod)%mod);
    }
    return 0;
}
/*
附上打表小程序
*/
#include<bits/stdc++.h>
using namespace std;
long long Sums(long long n,long long k) //函数定义
{
    long long sum = 0,N=1,K=1,M=1;
    if(k > 0 && k<=n)
    {
        for(long long i = 1;i<=n;i++)
        {
            N = N * i;
        }
 
        for(long long j = 1;j <= k;j++)
        {
            K = K * j;
        }
 
        for(long long h = 1;h <= n-k;h++)
        {
            M = M * h;
        }
        sum=N/(K*M);
        return sum;
    }
    else    
        return 0;
}
int main(){
    //freopen("in.txt","r",stdin);
    long long f[25];
    f[0]=0;
    f[1]=1;
    for(long long i=2;i<=20;i++)
        f[i]=f[i-1]+f[i-2];
    for(long long n=0;n<=20;n++){
        long long cur=0;
        for(long long k=0;k<=n;k++){
            long long cnk=Sums(n,k);
            //cout<<"C("<<k<<","<<n<<")="<<cnk<<endl;
            cur+=cnk*f[k];
        }
        cout<<cur<<endl;
    }
    return 0;
}

 

posted @ 2017-02-10 01:26  勿忘初心0924  阅读(256)  评论(0编辑  收藏  举报