UVA 11582 - Colossal Fibonacci Numbers!(取模运算)

题目链接 https://cn.vjudge.net/problem/UVA-11582

【题意】
输入两个非负整数a,b和正整数n(0<=a,b<=2^64, 1<=n<=1000),你的任务是计算f(a^b)除以n的余数,其中f(0)=0,f(1)=1,当i>=0时,f(i+2)=f(i+1)+f(i)

【思路】
所有计算都会对n取模,并且n的范围很小,设F(i)=f(i) mod n. 那么当F(i),F(i+1)和F(0),F(1)重复时,整个序列就开始重复,根据这个性质找出循环节即可.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef unsigned long long ull;

ull pw(ull x,ull n,ull mod){
    ull ans=1;
    while(n){
        if(n&1) ans=(ans*x)%mod;
        x=(x*x)%mod;
        n/=2;
    }
    return ans;
}

vector<ull> f;

int main(){
    int T;
    cin>>T;
    while(T--){
        f.clear();
        ull a,b,n;
        cin>>a>>b>>n;
        if(1ULL==n){ cout<<"0\n";continue; }
        f.push_back(0ULL);
        f.push_back(1ULL);
        ull cnt=0ULL;
        for(int i=2;;++i){
            f.push_back((f[i-1]+f[i-2])%n);
            ++cnt;
            if(f[i-1]==f[0] && f[i]==f[1]) break;
        }
        ull ans=f[pw(a%cnt,b,cnt)];
        cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值