一个数学问题,一旦出现循环确定循环节以后就能解决问题啦.
加上一个快速幂取模.需要注意的是数据范围是264,所以必须用unsigned long long才能解决问题.
觉得板子还是要会自己写,否则不同的题目具体有一些小的改变就会束手无策.
还有就是发现如果每次初始化数组的话就会超时,所以需要注意在不必要 的时候或者可以通过简单赋值的时候不要用memset进行初始化,挺耗时间.
看其他人为了避免超时进行打表,这也是一种思路.只是找到循环节需要多长的斐波那契数列理论上是n*n的,但是具体操作起来好像10 * n就可以找到.玄学.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cctype>
#include<queue>
#include<set>using namespace std;typedef long long ll;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
const int MAXN=1e3+15;int f[MAXN*MAXN];
ull a,b;
int n,x;
int len;void deal()
{memset(f,0,sizeof(f));f[0]=0%n; f[1]=1%n;int tmp=n*n;for(int i=2;i<=tmp+5;i++){f[i]=(f[i-1]+f[i-2])%n;if(f[i-1]==f[0] && f[i]==f[1]){len=i-1;break;}}
}ull quick_pow(ull a,ull b,ull len)
{ull ret=1;a=a%len;while(b){if(b&1) ret=a%len*ret%len;b>>=1;a=a*a%len;}return ret;
}int main()
{int T;scanf("%d",&T);while(T--){scanf("%llu%llu%d",&a,&b,&n);if(a==0 || n==1){printf("0\n");continue;}deal();x=(int)quick_pow(a,b,len);printf("%d\n",f[x]);}return 0;
}