原题链接:
https://vjudge.net/problem/UVA-11582
真香~
这道题,深深的打击到了我,在我知道提示的情况下 ,做了两个多小时,一直是runtime error,错了十几次,自闭了。。。。开始怀疑人生了,真的。
我怎么这么菜!!!
这道题,用到了一些我没学过的东西,说实话现在我还有点懵逼。
之前用的快速幂来计算a^b ,却显示runtime error,然后被迫学了分治法来计算 a^b,没办法。。。
一开始有个坑点是数据是小于2 的64次方的,用long long会爆掉,所以用unsigned long long,用%llu读。这里计算时有一个循环点的因为斐波那契f[1],f[2] 都为1,所以找下一个相邻模为1 的点即为循环点
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
int f[1010025];
int pow_mod(int x,unsigned long long y,int mm) //这里用分治法,仔细研究一下这段代码
{
if(y==0)
{return 1;}
int kk=pow_mod(x,y/2,mm);
long long ans=(long long)kk*kk%mm;
if(y%2==1) ans=ans*x%mm;
return (int)ans;
}
int main()
{
int T,i,n,m;
scanf("%d",&T);
while( T-- ){
unsigned long long a,b;
scanf("%llu %llu %d",&a,&b,&n);
if(a==0||n==1) //这个特判不要忘了
{
cout<<"0"<<endl;
}
else{
f[1]=1;
f[2]=1;
for(i=3;i<=n*n+1;i++) //这里找循环点
{
f[i]=(f[i-1]+f[i-2])%n;
if(f[i-1]==1&&f[i]==1)
{m=i-2; //m为循环点,找到后就跳出来
break;}
}
int ans=pow_mod(a%m,b,m);
if(ans==0) //这里加一个特判
{
ans=m;
}
printf("%d\n",f[ans]);}
}
return 0;
}
待更新。。。