The Luckiest number
64-bit integer IO format: %I64d Java class name: Main
Input
The last test case is followed by a line containing a zero.
Output
Sample Input
8 11 16 0
Sample Output
Case 1: 1 Case 2: 2 Case 3: 0
Source
首先,由题意可以得出,(10^x - 1)/ 9 * 8 = L * p(p是一个未知数,但必定是整数)。
然后对上式进行移项处理,得:(10^x - 1) = 9 * L * p / 8。
设m = 9 * L / gcd(L, 8),则有(10^x - 1) = m * p'。p’是必然存在的一个整数。
然后问题就转化成为了 10^x = 1(mod m),观察此式,显然,m和10必定互质。
于是根据欧拉定理,10^(Euler(m)) = 1(mod m) 。由于题目要求最小的解,解必然是Euler(m)的因子。
转自 OK_again
1 #include <bits/stdc++.h> 2 using namespace std; 3 using LL = long long; 4 const int maxn = 400110; 5 LL mul(LL a, LL b, LL mod) { 6 LL ret = 0; 7 while(b) { 8 if(b&1) ret = (ret + a) % mod; 9 a = (a<<1)%mod; 10 b >>= 1; 11 } 12 return ret; 13 } 14 LL quickPow(LL base,LL index,LL mod){ 15 LL ret = 1; 16 while(index){ 17 if(index&1) ret = mul(ret,base,mod); 18 index >>= 1; 19 base = mul(base,base,mod); 20 } 21 return ret; 22 } 23 bool np[maxn] = {true,true}; 24 int p[maxn],tot; 25 void init(){ 26 for(int i = 2; i < maxn; ++i){ 27 if(!np[i]) p[tot++] = i; 28 for(int j = 0; j < tot && p[j]*i < maxn; ++j){ 29 np[p[j]*i] = true; 30 if(i%p[j] == 0) break; 31 } 32 } 33 } 34 LL Euler(LL n){ 35 LL ret = n; 36 for(int i = 0; (LL)p[i]*p[i] <= n; ++i){ 37 if(n%p[i] == 0){ 38 ret = ret/p[i]*(p[i] - 1); 39 while(n%p[i] == 0) n /= p[i]; 40 } 41 } 42 if(n > 1) ret = ret/n*(n-1); 43 return ret; 44 } 45 vector<int>F; 46 void Fn(LL n){ 47 F.clear(); 48 for(int i = 0; i < tot && n > 1; ++i){ 49 while(n%p[i] == 0){ 50 n /= p[i]; 51 F.push_back(p[i]); 52 } 53 } 54 if(n > 1) F.push_back(n); 55 } 56 int main(){ 57 init(); 58 LL L; 59 int cs = 1; 60 while(scanf("%I64d",&L),L){ 61 LL m = 9*L/__gcd(L,8LL); 62 if(__gcd(m,10LL) != 1){ 63 printf("Case %d: 0\n",cs++); 64 continue; 65 } 66 LL x = Euler(m); 67 Fn(x); 68 for(auto it:F) 69 if(quickPow(10,x/it,m) == 1) x /= it; 70 printf("Case %d: %I64d\n",cs++,x); 71 } 72 return 0; 73 }