UVA11582 巨大的斐波那契数 ——抽屉原理 + 思维 + 余数

UVA11582

遇到类似mod很小时考虑从mod入手。

疑惑? 一定能够找到f(i-1) == 0 f(i) == 1吗

一定 假设出现循环,则对应的前一位一定相等,由此递推到第一位一定和某位相等

题意:

输入两个非负整数a, b和正整数a, b < 2^64,1 <=  n <= 1000,计算f(a^b) mod n。f为斐波那契数列,f(0) = 0, f(1) = 1;

思路:

不难发现当f(i-1) == 0, f(i) == 1时,出现循环。

n的范围很小,即余数最多有n种,所以最多n^2项就会出现重复

设t个数一循环,则f(a^b) == f(a^b mod t),用快速幂计算后者即可

注意当n == 1时需要单独判断 否则RE。

要用unsigned long long

// Decline is inevitable,
// Romance will last forever.
//#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <deque>
#include <vector>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define ll unsigned long long
#define LL unsigned long long
#define int unsigned long long
const int maxn = 1e6 + 10;
const int maxm = 1e3 + 10;
//const int P = 1e9 + 7;
int f[maxn];
int P;
LL power(LL a, LL b, LL P) {
    LL ans = 1 % P;
    for (; b; b >>= 1) {
        if (b & 1)  ans = ans * a % P;
        a = a * a % P;
    }
    return ans;
}
void solve() {
    f[0] = 0;
    f[1] = 1;
    LL a, b;
    int t = 0;
    cin >> a >> b >> P;
    for(int i = 2; i <=P * P; i++) {
        f[i] = (f[i-1] + f[i-2]) % P;
        if(f[i-1] == 0 && f[i] == 1) {
            t = i - 1;
            break;
        }
    }
    if(P == 1 || a == 0)
        cout << 0 << endl;
    else
        cout << f[power(a%t, b, t)] << endl;
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T; scanf("%d", &T); while(T--)
//    freopen("1.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    int T; cin >> T;while(T--)
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/120858227
今日推荐