Period of an Infinite Binary Expansion 題解
阿新 • • 發佈:2022-03-14
Solution
簡單寫一下思考過程,比較水的數論題
第一個答案几乎已經是可以背下來的,在此不再贅述
考慮我們已經知道了\((p,q)\),其中\((p \perp q) \wedge (q \perp 2)\),要求的是迴圈長度
首先看看樣例的\(\frac{1}{5}\)怎麼做呢
觀察答案,可以得到$$\frac{1}{5}=\sum_{t>0}(\frac{3}{16^t})$$
簡單思考一下,發現答案和\(p\)沒關係,和\(q\)的關係為
其中\(s,t \in \text{N}^\ast\)
簡單化下式子,等比數列求和得$$2^k-1=qS$$
即$$2^k \equiv 1 \pmod{q}$$
所以\(k|\varphi(q)\)
秒殺!
Code
#include <cstdio> #include <iostream> typedef long long LL; using namespace std; inline LL gcd(LL x, LL y) {return (y == 0) ? x : gcd(y, x % y);} LL p, q, ans1, ans2, d, n, i, id, phi; inline long long mul(long long a,long long b,long long c){ long long res = (a*b-(long long)((long double)a/c*b)*c)%c; return res < 0 ? res+c : res; } inline LL fpow(LL pnt) { LL res = 1, base = 2; for(; pnt; pnt >>= 1, base = mul(base, base, q)) if(pnt & 1) res = mul(res, base, q); return res; } inline void getphi(LL x) { phi = x; for(i = 2; i * i <= x; ++i) { if(!(x % i)) { phi = phi / i * (i - 1); while(!(x % i)) x /= i; } } if(x ^ 1) phi = phi / x * (x - 1); } int main() { while(~scanf("%lld/%lld",&p,&q)) { ++id; d = gcd(p, q); p /= d, q /= d; ans1 = 1; while(!(q & 1)) ++ans1, q >>= 1; if(q == 1) ans2 = 0; else { getphi(q); ans2 = 0x7f7f7f7f; for(i = 1; i * i <= phi; ++i) if(!(phi % i)) { if(fpow(i) == 1) {ans2 = i; break;} if(fpow(phi / i) == 1) ans2 = phi / i; } } printf("Case #%lld: %lld,%lld\n",id,ans1,ans2); } return 0; }