luogu P1962 斐波那契数列 矩阵运算

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/86297407

题目

https://www.luogu.org/problemnew/show/P1962

题解

刚看到题,就想着直接用
f [ i ] = f [ i 1 ] + f [ i 2 ] f[i]=f[i-1]+f[i-2]
递推下去不就行了。然后一看数据范围,

对于 60% 的数据: n ≤ 92
对于 100% 的数据: n在long long(INT64)范围内。

要凉,不过六十分还是好写的,于是就打了六十分代码:
下面是评测结果以及代码(六十分暴力):
https://www.luogu.org/recordnew/show/15330255

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=93;
const ll mod=1000000007;
inline int read()
{
    ll f=1,num=0;
    char ch=getchar();
    while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
    while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
    return num*f;
}
ll f[maxn];
int main()
{
    f[1]=f[2]=1;
    for (int i=3;i<=maxn;++i)
        f[i]=(f[i-1]+f[i-2])%mod;
    ll n=read();
    printf("%lld\n",f[n]%mod);
}

整的很短!!!!!!
正解是个矩阵运算(快速幂),那就写呗!!!
请出代码(扔下代码赶紧逃):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
inline ll read()
{
    ll f=1,num=0;
    char ch=getchar();
    while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
    while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
    return num*f;
}
struct mat
{
	ll a[2][2];
};
inline mat mul(mat x,mat y)//矩阵乘法 
{
	mat res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
                (res.a[i][j]+=x.a[i][k]%mod*y.a[k][j]%mod)%=mod;
    return res;
}
inline void power(ll n)//矩阵快速幂 
{
	mat c,res;
    c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
	c.a[1][1]=0;//基础矩阵赋值 
    memset(res.a,0,sizeof res.a);
    res.a[0][0]=1;res.a[0][1]=1;//递推数组初值:f[1]=1,f[2]=1
    while (n)
    {
        if (n&1)
			res=mul(res,c);
        c=mul(c,c);
        n>>=1;
    }
    printf("%lld\n",res.a[0][0]);
}
int main()
{
    ll n=read();
    if (n==1)
		puts("1");//注意特判 
    else
		power(n-2);//计算基础矩阵
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/86297407
今日推荐