Colossal Fibonacci Numbers! UVA - 11582 (数论,幂求模,规律周期)

直击题目:https://vjudge.net/problem/41990/origin

题目大意:

给出三个数,a,b,n;其中a,b<2^64;n<1000。已知Fibonacc的数的递推公式,f[0]=0,f[1]=1;f[i+2]=f[i+1]+f[i].然后求出f[a^b]对n取模的值。

题解:首先看到的是这个公式,f[i]=f[i-1]+f[i-2],那么假设f[a^b]=f[i]。而f[a^b]%n=f[i]%n=f[i-1]%n+f[i-2]%n.然后根据递推的关系可以看出,其实在求的过程中对每一个f[i]取模就可以了。当进行到这里的时候该怎么化简一下a^b呢?显然没有这么大的数组。这时可以考虑一下有没有规律周期可以寻找。通过打表,可以看出,其实对于每一个n,都有一个f[i]对n取余的循环周期,那么假设这个周期是g[n],表示以n模的Fibonacc周期。然后在回头看a^b,因为是有周期的,那么a^b对他的周期取余就可以了,这就涉及到了幂取模的分治法。然后就可以得出答案了。

注意:这个题要用cin才行,scanf会wa,真是wa的都无语了。当然还要注意边界,当n==1或a==0是,都是0;

还有一点就是,因为a很大,当进行幂取模前先对a取模一下


#include <iostream>
#include<bits/stdc++.h>

using namespace std;
 unsigned long long a,b;
int f[1050][65000];
int g[1055];
int pow_mod(unsigned long long a,unsigned long long b,int n)
{
    if(b==0)return 1;
    int x=pow_mod(a,b/2,n);
    int ans=x*x%n;
    if(b%2==1)ans=ans*a%n;
    return ans;
}
int main()
{
    for(int i=2; i<1010; i++)
    {
        f[i][0]=0;
        f[i][1]=1;
        for(int j=2;; j++)
        {
            f[i][j]=(f[i][j-1]+f[i][j-2])%i;
            if(f[i][j]==1&&f[i][j-1]==0)
            {
                g[i]=j-1;
                break;
            }
        }
    }
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>n;
        if(n==1||a==0)
        {
            cout<<0<<endl;
        }
        else
        {
            int x=pow_mod(a%g[n],b,g[n]);
            cout<<f[n][x]<<endl;
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值