最近各种破事忙死了
终于开始做题了
紫薯第10章第一题,come on
设g(i)=f(i) mod n,当二元组(g(i)、g(i+1))出现重复时,整个序列就开始重复(这一话怎么也不懂,请大神解释)
余数最多n种,所以最多n^2项就会出现重复。设周期为m,只需计算出g(0)~g(n^2)项,然后计算g(a^b)等于其中的哪一项即可
但是,n<=1000,那么n方的规模会达到10^6,显然f(n^2)有些庞大
我们可以利用(a+b)mod n=((a mod n)+(b mod n))mod n 优化
那么g(i+2)=g(i+1)+g(i)=(f(i+1)mod n + f(i)mod n )mod n=(g(i+1)+g(i))mod n
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int T; int n; unsigned long long a,b; int g[2005001]; int PowerMod(unsigned long long a, unsigned long long b, int c) { int ans = 1; a = a % c; while(b>0) { if(b % 2 == 1) ans = (ans * a) % c; b = b/2; a = (a * a) % c; } return ans; } int main() { cin>>T; while (T--){ cin>>a>>b>>n; if(n==1) { puts("0"); continue; } int m=1; g[1]=1;g[2]=1; int i=3; while (1){ g[i]=(g[i-1]+g[i-2])%n; if (g[1]==g[i-1]&&g[2]==g[i]) break; i++; } m=i-2; int s=PowerMod(a,b,m); cout<<g[s]<<endl; } }
注意n==0的时候,可能会发生re