1. 程式人生 > >矩陣快速冪 牛客網哈爾濱理工大學第七屆程式設計競賽初賽(高年級組)H題

矩陣快速冪 牛客網哈爾濱理工大學第七屆程式設計競賽初賽(高年級組)H題

題目描述

小d接到了一個佈置會場的任務。

他需要將貴賓觀眾席的椅子排成一排,一共需要N個。

上級領導指示,他只能使用兩種椅子。(A型別和B型別)並且假設每種椅子的數量都是無限的。

而其如果想要擺置一個B型別的椅子,對應就需要必須有連續兩個一起佈置。換句話說,就是如果出現了B型別的椅子,其必須且只有兩個連著B型別的椅子。

小d突然想知道對應N個椅子排成一列,他能夠有多少種佈置的方式.

輸入描述:

本題包含多組輸入第一行輸入一個整數t,表示測試資料的組數
每組測試資料包含一行,輸入一個整數N,表示一共需要擺放的椅子數量
t<=1000
1<=N<=100000000000000000(10^18)

輸出描述:

每組測試資料輸出包含一行,表示一共有多少種佈置的方式,方案數可能會很大,輸出對1000000007取摸的結果。
//快速冪
#include <bits/stdc++.h>
using namespace std;
int quickpow(int a,int b)
{
    int r=1;
    while(b)
    {
        if(b%2)r=r*a%mod;
        a=a*a%mod;
        b=b/2;
    }
    return r;
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&a,&b))
    {
        cout<<quickpow(a,b)<<endl;
    }
    return 0;
}

矩陣快速冪

#include <bits/stdc++.h>
using namespace std;
const int maxn=1000000007;
struct node
{
    long long a[2][2];
};
node matrix(node x,node y)
{
    node r;
    memset(r.a,0,sizeof(r.a));
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            for(int k=0;k<2;k++)
            {
                r.a[i][j]+=x.a[i][k]*y.a[k][j];
                r.a[i][j]%=maxn;
            }
        }
    }
    return r;
}
long long quickpow(long long n)
{
    node c,r;
    memset(r.a,0,sizeof(r.a));
    c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
    c.a[1][1]=0;
    r.a[0][0]=r.a[0][1]=1;
    while(n)
    {
        if(n%2) r=matrix(c,r);
        c=matrix(c,c);
        n/=2;
    }
    return r.a[0][1];
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        long long k;
        scanf("%lld",&k);
        cout<<quickpow(k)<<endl;
    }
    return 0;
}