uva 12169
1 /* 巨大的斐波那契数列_________________________________________________________________________________ 2 3 #include <iostream> 4 #include <map> 5 #include <cmath> 6 #include <vector> 7 #include <cstdio> 8 #include <string> 9 #include <cstring> 10 #include <algorithm> 11 using namespace std; 12 #define fir first 13 #define sec second 14 #define pb(x) push_back(x) 15 #define mem(A, X) memset(A, X, sizeof A) 16 #define REP(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) 17 #define rep(i,l,u) for(int (i)=(int)(l);(i)>=(int)(u);--(i)) 18 #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e) 19 20 typedef pair<long,long> pll; 21 22 23 int T,n; 24 const int mod=1e9+7; 25 const int maxn=1e3+10; 26 typedef unsigned long long ULL; 27 ULL qsm(ULL a, ULL b, ULL mod) // 0<=a<=ULL 0<=b<=ULL 28 { 29 a=a%mod; 30 ULL res=1; 31 while(b) 32 { 33 //a=a%mod;(有时候n的值太大了会超出long long的储存,所以要先取余) 34 if(b&1)//&位运算:判断二进制最后一位是0还是1,&的运算规则为前后都是1的时候才是1; 35 res=res*a%mod; 36 b=b>>1;//相当于除以2; 37 a=a*a%mod; 38 } 39 return res; 40 } 41 ULL f[maxn*maxn+1000]; 42 int main() 43 { 44 freopen("in.txt","r",stdin); 45 //while(cin>>n) 46 while(cin>>T&&T) 47 { 48 REP(kase,1,T) { 49 ULL ans; 50 ULL a,b,n; 51 cin>>a>>b>>n; 52 if(a==0||n==1) ans=0; 53 else 54 { 55 56 f[1]=1; 57 f[0]=0; 58 int M; 59 REP(i,2,n*n+10) 60 { 61 f[i]=(f[i-1]+f[i-2])%n; 62 if(f[i]==f[1]&&f[i-1]==f[0]) 63 { 64 M=i-1; 65 break; 66 } 67 } 68 ULL t=qsm(a,b,M); 69 ans=f[t]; 70 } 71 cout<<ans<<endl; 72 } 73 } 74 return 0; 75 } 76 77 /* 78 note : typedef 给数据类型加个名字, 是一条语句,只需要放在宏定义之后即可(即可全局,可main 函数内). 79 对于循环节类的问题,只需要找到刚开始的起始项,之后找到周期,利用周期的一致性,将查询到 80 项直接进行周期M取模即可,注意f[0]是否进行了赋值,如果没有的话还需要f[0]=f[M]. 81 debug : 范围比较大需要用到ull 82 re的原因有可能是因为数据类型不一致,(返回 runtime error ) 83 for(int i=1;i<=(unsigned long long)100;i++) 84 85 optimize: 分析出n的范围,预处理出来,可以避免大量的查询.分析出来了所有的基本可能情况. 86 改进快速幂取模, 87 命名 进行程序变量的命名的时候,最好直接指代原来的变量例如 预处理n的时候,直接就是n就可以. 88 REP(n,2,maxn) 89 */