Colossal Fibonacci Numbers! UVA - 11582

题目链接:UVA - 11582

本题的关键就是对于斐波那契数列,如果f(n)和f(n + 1)与之前某个f(i)和f(i + 1)一样,则f(n + 2)也会和f(i + 2)一样,于是乎接下来的都一样了,由于f(n)对mod求模,则每个f的值都在0~mod之间,最多组合有mod*mod种,也就是说可以在规定时间内知道循环的,而且斐波那契数列的循环节是纯循环的,所以我们为了简便,就取f(1),f(2)为基准,也就是出现了f(i),f(i+1)均为1的时候,就结束。此时循环节大小为i - 2,我们把m设为i - 2,我们最后通过求f(ab)对于mod的模实际上就是求f(ab%m)对mod的模。注意当a = 0或者mod = 0时要特判。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
int mod, m;
ll f[1000005];
int power(ll a, ll b) {//求a^b对于m求模的快速幂,ab%m == ((a % m) * (b % m)) % m
    if(b == 0)
        return 1;
    int temp = power(a, b / 2);
    temp = (ll)temp * temp % m;
    if(b & 1)
        return temp * a % m;
    else
        return temp;
}

int main()
{
    int t;
    ll a, b;
    scanf("%d", &t);
    f[1] = f[2] = 1;
    for(int cnt = 0; cnt < t; cnt++)
    {
        scanf("%llu %llu %d", &a, &b, &mod);
        if(mod == 1 || a == 0)//特判
        {
            printf("0\n");
            continue;
        }
        for(int i = 3; i <= 1000000; i++)//找到循环节
        {
            f[i] = (f[i - 1] + f[i - 2]) % mod;
            if(f[i] == 1 && f[i] == f[i - 1])//如果出现了f[i]和f[i + 1]都是1,则出现循环了,循环节就是从1到达i-2,长度为i-2
            {
                m = i - 2;//循环节长度
                break;
            }
        }
        printf("%llu\n", f[power(a % m , b)]);
    }
    return 0;
}

 

posted @ 2020-08-04 18:38  funforever  阅读(116)  评论(0编辑  收藏  举报