2019牛客第九场A题 (The power of Fibonacci) 斐波那契循环节

题意:给出斐波那契数列, 。给两个数n,m。求

题解:考虑皮萨诺周期 , 注意到 , 并且 。于是, 。7812500是一个不大的数,预处理前7812500项的前缀和,然后得到答案分别对和 的余数,从而可以使用中国剩余定理得到答案。

#include 
#include 
#define int long long
#define FOR(i, x, y) for (std::decay::type i = (x), _##i = (y); i < _##i; ++i)
using std::cin, std::cout, std::endl;
using pii = std::pair;
const int mod = 1e9;
const int mod2 = 512;
const int mod5 = 1953125;
const int cir2 = 768;
const int cir5 = 7812500;

int bin(int x, int n, int MOD)
{
    int ret = MOD != 1;
    for (x %= MOD; n; n >>= 1, x = x * x % MOD)
        if (n & 1)
            ret = ret * x % MOD;
    return ret;
}

int ex_gcd(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int ret = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return ret;
}

int CRT(int *m, int *r, int n)
{
    if (!n)
        return 0;
    int M = m[0], R = r[0], x, y, d;
    FOR(i, 1, n)
    {
        d = ex_gcd(M, m[i], x, y);
        if ((r[i] - R) % d)
            return -1;
        x = (r[i] - R) / d * x % (m[i] / d);
        R += x * M;
        M = M / d * m[i];
        R %= M;
    }
    return R >= 0 ? R : R + M;
}

int32_t main()
{
    int n, m;
    cin >> n >> m;
    int r2 = n % cir2, r5 = n % cir5;
    int fib[3] = {0, 1, 1};
    int sum2 = 0, sum5 = 0;
    int sum_in_cir2 = 0, sum_in_cir5 = 0;
    for (int i = 0; i < cir5; i++)
    {
        if(i>=3)
            fib[i % 3] = (fib[(i + 2) % 3] + fib[(i + 1) % 3]) % mod;
        if (i < cir2)
        {
            (sum_in_cir2 += bin(fib[i % 3], m, mod2)) %= mod2;
        }
        if (i < cir5)
        {
            (sum_in_cir5 += bin(fib[i % 3], m, mod5)) %= mod5;
        }
        if (i == r2)
        {
            sum2=sum_in_cir2;
        }
        if (i == r5)
        {
            sum5=sum_in_cir5;
        }

    }
    (sum2 += sum_in_cir2 * (n / cir2)%mod2) %= mod2;
    (sum5 += sum_in_cir5 * (n / cir5)%mod5) %= mod5;
    int mm[] = {mod2, mod5};
    int rr[] = {sum2, sum5};
    int ans = CRT(mm, rr, 2);
    cout << ans << endl;
}

参考:

  • 皮萨诺周期 (this version)
  • 中国剩余定理的代码来自于 ECNU 退役队伍 F0RE1GNERS 的模板 https://github.com/zerolfx/template

你可能感兴趣的:(2019牛客第九场A题 (The power of Fibonacci) 斐波那契循环节)