山东农业大学校赛 K wyh的数列 循环节 巨坑 水题

本文解决了一个涉及大数运算和斐波那契数列的算法问题,通过寻找循环节的方法来高效计算F(a^b)%c,其中a^b可能非常大,而c相对较小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://www.nowcoder.com/acm/contest/93/K
来源:牛客网

题目描述

wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)

一天他突发奇想,想求F(a^b)%c
输入描述:

输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行三个数 a,b,c (a,b< =2^64) (1 < c<1000)

输出描述:

输出第a^b项斐波那契数对c取余的结果

示例1
输入

3
1 1 2
2 3 1000
32122142412412142 124124124412124 123

输出

1
21
3

解题思路 :
观察到 c很小 根据经验可知 可找循环节。
不过要注意的是 a b 有2的64次方 longlong存不下 要开ull
史诗级巨坑。。。。。。。。。。 气死我了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<queue>
#include<cmath>
#define ull unsigned long long
using namespace std;
ull loop[3000];
ull qickpow(ull a,ull b,ull MOD){
    ull ans=1;
    a%=MOD,b%=MOD;
    while(b){
        if(b&1) ans=(ans%MOD*a%MOD)%MOD;
        b>>=1;
        a=(a%MOD*a%MOD)%MOD;
    }
    return ans;
}
ull F(int len,ull MOD){
    if(len==0) return 0;
    ull f1=0,f2=1;
    for(int i=2;i<=len;i++){
        ull cnt=(f1%MOD+f2%MOD)%MOD;
        f1=f2;
        f2=cnt;
    }
    return f2;
}
int main() {
    for(int i=2;i<=1000;i++){
        ull f1=1,f2=1;
        for(int j=0;j<1000000;j++){
            if(f1==1 && f2==1 && j){
                loop[i]=j;
                //cout<<j<<endl;
                break;
            }
            ull cnt=(f2+f1)%i;
            f1=f2;
            f2=cnt;
        }
    }
    int T;
    cin>>T;
    while(T--){
        ull a,b,c;
        cin>>a>>b>>c;
        //cout<<loop[c]<<endl;
        ull cnt=qickpow(a,b,loop[c]);
        cout<<F(cnt,c)%c<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值