Fibonacci前n项和 (矩阵乘)

大家知道Fibonacci数列吧, f[1]=1, f[2]=1, f[3]=2, f[4]=3…, 也就是f[n]=f[n-1]+f[n-2],现在问题很简单,输入n和m,求前n项和取模m。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define mem(s,t) memset(s,t,sizeof(s))
#define pq priority_queue
#define pb push_back
#define fi first
#define se second
#define ac return 0;
#define ll long long
#define TLE std::ios::sync_with_stdio(false);   cin.tie(NULL);   cout.tie(NULL);   cout.precision(10);
string str;
set <int> id;
int cnt[30000+10];
vector <int> edge[30000+10];
//pq<int , vector<int> ,greater<int> >q;
pq<int>q;
vector <int> ans;
const int maxn = 4;
struct mat
{
    int m[maxn][maxn];
}  unit;
mat operator * (mat a,mat b)
{
    mat ret;
    ll sum;
    for(int i=1; i<=3; i++)
        for(int j=1; j<=3; j++)
        {
            sum = 0;
            for(int k=1; k<=3; k++)
                sum += (ll)a.m[i][k]*b.m[k][j];
            ret.m[i][j] = sum;
        }
    return ret;
}
void init_unit()
{
    for(int i=1; i<=3; i++)
        for(int j=1; j<=3; j++)
        {
            if(i==j) unit.m[i][i] = 1 ;
            else unit.m[i][j] = 0;
        }
}
mat MultiPow(mat arr,ll n)
{
    mat ret=unit;
    while(n)
    {
        if(n&1)
            ret = ret*arr;
        n>>=1;
        arr=arr*arr;
    }
    return ret;
}
int main()
{
    TLE;
    int k,n;
    cin>>n>>k;
    init_unit();
    mat arr=unit;
    arr.m[1][2]=1;    arr.m[3][2]=1;
    arr.m[3][3]=0;    arr.m[2][3]=1;
    arr=MultiPow(arr,n-1);
    ll ans=0;
    for(int i=1; i<=3; i++)
        ans+=arr.m[1][i];
    cout<<ans%k<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Shallow-dream/p/11683326.html