UVA11582巨大的斐波那契数
Posted nsd-email0820
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA11582巨大的斐波那契数相关的知识,希望对你有一定的参考价值。
题意
输入两个非负整数a、b和正整数n(0<=a,b<264,1<=n<=1000),你的任务是计算f(ab)除以n的余数,f(0) = 0, f(1) = 1,且对于所有非负整数i,f(i + 2) = f(i + 1) + f(i)。
分析
首先可以观察到n是很小的,意思是n的完全剩余系的元素个数也不超过1e3个,所以设F[i]=f(i)%n,则F函数的循环节也不会超过1e3的长度(应该是吧,我推测的)
多组数据,我们就预处理出每个n的循环节,再跑快速幂取模就行了,注意:ab取模传的参数第一位不是a而是a%mod
最近迷上了常数优化,啥代码都带个读优和register :)
代码
- #include<bits/stdc++.h>
- using namespace std;
- #define N 1010
- #define RT register
- #define ull unsigned long long
- ull q,a,b,mod;
- ull t[N],f[N][N*6];
- template<class T>
- inline void read(T &x)
- {
- x=0;ull f=1;static char c=getchar();
- while(c<‘0‘||c>‘9‘) {if(c==‘-‘)f=-1;c=getchar();}
- while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘,c=getchar();}
- x*=f;
- }
- inline ull ksm(ull a,ull b,ull mod)
- {
- ull ret=1;
- while(b)
- {
- if(b&1)ret=(ret*a)%mod;
- a=(a*a)%mod;
- b>>=1;
- }
- return ret;
- }
- int main()
- {
- read(q);
- for(RT int n=2;n<=1000;n++)
- {
- f[n][0]=0,f[n][1]=1;
- for(RT int i=2;i;i++)
- {
- f[n][i]=(f[n][i-1]+f[n][i-2])%n;
- if(f[n][i]==1&&f[n][i-1]==0)
- {
- t[n]=i-1;
- break;
- }
- }
- }
- while(q--)
- {
- read(a),read(b),read(mod);
- if(mod==0||mod==1){printf("0 ");continue;}
- printf("%llu ",f[mod][ksm(a%t[mod],b,t[mod])]);
- }
- }
以上是关于UVA11582巨大的斐波那契数的主要内容,如果未能解决你的问题,请参考以下文章