HDU4549 费马小定理应用

来源:互联网 发布:mysql substr 编辑:程序博客网 时间:2024/05/18 15:26

M斐波那契数列Fnn是一种整数数列,它的定义如下:

F00 = a
F11 = b
Fnn = Fn−1n−1 * Fn−2n−2 ( n > 1 )

现在给出a, b, n,你能求出Fnn的值吗?
Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
Output
对每组测试数据请输出一个整数Fnn,由于Fnn可能很大,你只需输出Fnn对1000000007取模后的值即可,每组数据输出一行。
Sample Input
0 1 0
6 10 2
Sample Output
0
60

脑子太直没想到这个
费马小定理就是a^b%c中如果ac互质那么等同于a^(b%(c-1))
没看到a和b的范围推了裸的斐波那契。。
有点傻逼

#include<iostream>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<cstring>#include<cstdio>using namespace std;typedef long long ll;ll mo = 1e9 + 7;struct p{    ll q[2][2];};p cheng(p q, p w){    p fh;    for (long long a = 0; a < 2; a++)    {        for (long long b = 0; b < 2; b++)        {            fh.q[a][b] = 0;            for (long long c = 0; c < 2; c++)            {                fh.q[a][b] += (q.q[a][c] * w.q[c][b]) % (mo - 1);                fh.q[a][b] %= mo-1;            }        }    }    return fh;}p ksm(p ds, long long zs){    p fs = { 1,0,0,1 };    while (zs)    {        if (zs & 1)fs = cheng(fs, ds);        ds = cheng(ds, ds);        zs >>= 1;    }    return fs;}long long ks(long long ds, long long zs){    long long fs = 1;    while (zs)    {        if (zs & 1)fs *= ds%mo;        fs %= mo;        ds *= ds;        ds %= mo;        zs >>= 1;    }    return fs;}int main(){    long long aa, bb, n;    while (cin >> aa >> bb >> n)    {        if (n == 0)        {            cout << aa%mo << endl;            continue;        }        if (n == 1)        {            cout << bb%mo << endl;            continue;        }        p we = ksm({ {1,1,1,0} }, n - 1);        long long af0 = 1, af1 = 0, bf0 = 0, bf1 = 1;        long long zsa = we.q[0][1]%(mo-1), zsb = we.q[0][0]%(mo-1);        long long ww = (ks(aa, zsa) +mo)% mo, ee = (ks(bb, zsb)+mo) % mo;        cout << (ww*ee+mo)%mo << endl;    }}
原创粉丝点击