<p><span style="font-size:18px;">分析:定义(x,y),x代表a的个数,y代表b的个数。</span></p> <p><span style="font-size:18px;"> 先找规律f(0)=a (1,0)
</span></p> <p><span style="font-size:18px;"> f(1)=b; (0,1)
</span></p> <p><span style="font-size:18px;"> f(2)=ab (1,1)</span></p> <p><span style="font-size:18px;"> f(3)=abb (1,2)</span></p> <p><span style="font-size:18px;"> f(4)=abbab (2,3)</span></p> <p><span style="font-size:18px;"> f(5)=abbababb (3,5)</span></p> <p><span style="font-size:18px;"> f(6)=abbababbabbab (5,8)</span></p> <p><span style="font-size:18px;"> ......</span></p> <span style="font-size:18px;">由规律可知,f(n)=a^fibonacci(n-2)*b^fibonacci(n-1),但是n=500的时候fibonacci(500)
就已经超过1e100了,又因为求的数要%1000000007,而1000000007是素数,由费马小定理可
知:若p为素数,a^(p-1)≡1 (mod p)。a^b%p=(<span style="font-size:18px;">a^(k(p-1)+c)</span>)%p=(<span style="font-size:18px;">a^(k(p-1))*a^c</span>)%p=a^c%p
。所以f(n)=a^<span style="font-size:18px;">(<span style="font-size:18px;">fibonacci(n-2)%<span style="font-size:18px;">1000000006</span></span>)*b^(<span style="font-size:18px;">fibonacci(n-1)%<span style="font-size:18px;">1000000006</span></span>)%<span style="font-size:18px;">1000000007.</span></span></span>
#include <cstdio>
const int N = 1000000007;
struct mat{
int n, m;
long long a[12][12];
};
mat aa;
long long dfs(long long a, long long n)
{
long long s;
if(n == 1)return a;
if(n%2)
{
s = dfs(a,n/2);
return ( (s*s)%N )*a%N;
}
else
{
s = dfs(a,n/2);
return s*s%N;
}
}
mat mul(mat a,mat b)
{
long long s;
int i, j ,k;
mat c;
for ( i = 1; i <= 2; i++)
{
for ( j = 1; j <= 2; j++)
{
s = 0;
for ( k = 1; k <= 2; k++)
{
s += (a.a[i][k] * b.a[j][k]) % (N-1);
}
c.a[i][j] = s;
}
}
return c;
}
mat mul_mi(mat a,long long n)
{
mat s;
if(n == 1)return a;
if(n%2)
{
s = mul_mi(a,n/2);
return mul( mul(s,s), a);
}
else
{
s = mul_mi(a,n/2);
return mul(s,s);
}
}
int main()
{
long long a, b, n, m, s1, s2, i, j, k;
mat c;
aa.a[1][1] = aa.a[1][2] = aa.a[2][1] = 1;
aa.a[2][2] = 0;
while(scanf("%lld%lld%lld",&a,&b,&n) != EOF)
{
if(n == 0)printf("%lld\n",a);
if(n == 1)printf("%lld\n",b);
if(n == 2)printf("%lld\n",a*b%N);
if(n > 2)
{
c = mul_mi(aa,n-2);
s1 = dfs(a,(c.a[2][1] + c.a[2][2]) %(N-1) );
s2 = dfs(b,(c.a[1][1] + c.a[1][2]) %(N-1) );
printf("%lld\n",s1*s2%N);
}
}
return 0;
}nyoj 1000 又见斐波那契数列
最新推荐文章于 2019-05-07 19:34:46 发布
本文探讨了一个基于斐波那契数列的字符串生成问题,通过使用矩阵快速幂算法来高效计算大数值下的斐波那契数,并利用费马小定理解决了模运算的问题。文章还提供了一段C++实现代码。
583

被折叠的 条评论
为什么被折叠?



