【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  :)

代码

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 1010  
  4. #define RT register   
  5. #define ull unsigned long long  
  6. ull q,a,b,mod;  
  7. ull t[N],f[N][N*6];  
  8. template<class T>  
  9. inline void read(T &x)  
  10. {  
  11.     x=0;ull f=1;static char c=getchar();   
  12.     while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}  
  13.     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}  
  14.     x*=f;  
  15. }  
  16.   
  17. inline ull ksm(ull a,ull b,ull mod)  
  18. {  
  19.     ull ret=1;  
  20.     while(b)  
  21.     {  
  22.         if(b&1)ret=(ret*a)%mod;  
  23.         a=(a*a)%mod;  
  24.         b>>=1;  
  25.     }  
  26.     return ret;  
  27. }  
  28.   
  29.   
  30. int main()  
  31. {  
  32.     read(q);  
  33.     for(RT int n=2;n<=1000;n++)  
  34.     {  
  35.         f[n][0]=0,f[n][1]=1;  
  36.         for(RT int i=2;i;i++)  
  37.         {  
  38.             f[n][i]=(f[n][i-1]+f[n][i-2])%n;  
  39.             if(f[n][i]==1&&f[n][i-1]==0)  
  40.             {  
  41.                 t[n]=i-1;  
  42.                 break;  
  43.             }     
  44.         }  
  45.     }  
  46.     while(q--)  
  47.     {  
  48.         read(a),read(b),read(mod);  
  49.         if(mod==0||mod==1){printf("0 ");continue;}  
  50.         printf("%llu ",f[mod][ksm(a%t[mod],b,t[mod])]);  
  51.     }  
  52. }  
原文地址:https://www.cnblogs.com/NSD-email0820/p/9857651.html