链接: Best Solver
题目分析:
这个题目的关键点是需知道“共轭”.
如 :(A√B + C√D) 和 (A√B - C√D) 是共轭的
这个有一个规律 (A√B + C√D)^n + (A√B - C√D)^n 是一个整数(这里大家可以写写试试看)。
由题目可知:
因为我们要求的是:(5+2√6)^(1+2x), 我们可以构造一对共轭数。 (5-2√6),
因为0<(5-2√6) < 1, 所以 0<(5-2√6)^n < 1
故: 我们的式子由上述共轭的性质可知 y = (5+2√6)^(1+2x) + (5-2√6)^(1+2x) - 1;(y是要向下取整)
然后我们的y其实是有一个递推关系的:
F(n) = 10*F(n-1) - F(n-2).
证明如下:
设: Sn = (5+2√6)^n + (5-2√6)^n;
Sn * ( (5+2√6) + (5-2√6) ) = Sn * 10 = Sn+1 + Sn-1 * 1;
故: Sn+1 = 10*Sn - Sn-1;
=================================================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL INF = 0xfffffff; const LL maxn = 50005; int dp[maxn]; int GetLoop(int m) { memset(dp, 0, sizeof(dp)); dp[0] = 2%m; dp[1] = 10%m; for(int i=2; i<=maxn-5; i++) { dp[i] = (10*dp[i-1] - dp[i-2]+m)%m; if(dp[i] == dp[1] && dp[i-1] == dp[0]) return i-1; } return -1; } int QuickPow(int a,int b,int MOD) { int ans = 1, k = a; while(b) { if(b%2 == 1) ans = (ans * k)%MOD; k = (k * k)%MOD; b /= 2; } return (ans+1)%MOD; } int main() { int T, n, m, cas = 1; cin >> T; while(T--) { cin >> n >> m; int LoopNode = GetLoop(m); int ans = QuickPow(2, n, LoopNode); printf("Case #%d: %d ",cas++, (dp[ans%LoopNode] - 1)%m); } return 0; }