F - Problem of Precision
阿新 • • 發佈:2020-07-21
神仙題,完全沒想到。
樸素想法,我們開4*4的矩陣,分別記錄\(\sqrt{2}\),\(\sqrt{3}\),\(\sqrt{6}\),\(1\)的係數,然後快速冪。
但是我們沒法對係數取模,因此不能確定整數部分。
再分析一下,題目讓我們求\((\sqrt{2} + \sqrt{3})^{2n}\),那不就是\((5 + 2\sqrt{6})^{n}\)嗎,這成功減少了一個無理數,我們繼續用剛才的方法。
雖然依舊不能算出答案,但是矩陣只要2*2了。
接下來就是我不會的東西了
考慮上面的矩陣,我們可以利用它來求得準確解\(a+b\sqrt{6}\),其中\(a\)可以準確知道,並在計算過程中取模
採用數學方法消去\(b\sqrt{6}\),我們構造\((5-2\sqrt{6})^n\),其準確值為\(a-b\sqrt{6}\)
\((5+2\sqrt{6})^n + (5-2\sqrt{6})^n = a+b\sqrt{6}+a-b\sqrt{6}=2a\)
因為\(0 < 5-2\sqrt{6} < 1\),所以\(0 < (5-2\sqrt{6})^n < 1\)
令\(t = (5-2\sqrt{6})^n\),\(\lfloor (5+2\sqrt{6})^n \rfloor = \lfloor 2a - t \rfloor = 2a - 1\)
利用矩陣乘法計算\(a\)
其實可以類似複數定義一種數為\(x+y\sqrt{6}\),直接算乘法。
#include<bits/stdc++.h> using namespace std; const int mod = 1024; struct node{ long long a,b; }; node operator * (node x,node y){ node c; c.a = (x.a * y.a % mod + x.b * y.b % mod * 6 % mod ) % mod; c.b = (x.a * y.b % mod + x.b * y.a % mod ) % mod; return c; } node ksm(node x,int y){ node z; z.a = 1; z.b = 0; while(y){ if(y & 1) z = z * x; y >>= 1; x = x * x; } return z; } int main(){ int T; scanf("%d",&T); while(T --){ int n; scanf("%d",&n); node x; x.a = 5; x.b = 2; node y; y.a = 5; y.b = -2; x = ksm(x,n); y = ksm(y,n); long long ans = (x.a + y.a) % mod; ans = (ans - 1 + mod) % mod; printf("%lld\n",ans); } return 0; }