The Luckiest Number ( 欧拉定理变形

# 题意

多组测试样例,给定一个L,求位数最少的全由8组成的数是L的倍数,输出时加上"Case t: "

数据范围:

1 ≤ L ≤ 2*109

# 题解

x位数字每一位是8的数字表示为8*(10x-1)/9

10x有x+1位,-1为x位由9构成,再除9就是x位由1构成的数字,乘8就是由x位8构成的数字

即转化成了求最小的x使得

   L|8*(10x-1)/9

L*k=8*(10x-1)/9

9*L*k=8*(10x-1)

gcd(9*L,8)=gcd(L,8)=d

(9*L)/d * k=8/d*(10x-1)

u=(9*L)/d ,v=8/d

u*k=v*(10x-1)

因为除了最大公约数所以u、v互质

因为u<v

u | (10x-1)

即10x-1 ≡ 0(mod u)

10x ≡ 1 (mod (9L/d))

欧拉定理中aφ(n) ≡ 1 (mod n),a和n互质

所以必定存在一个和10互质的u满足上式

但是只用欧拉定理无法求出最小的解

引理:

正整数a,n互质,则满足a≡ 1 mod( n )的最小正整数x0是φ(n)的约数

直观上将欧拉定理的φ(n)拆成φ(n) , ax*y≡ 1 mod( n )

反证法证明:

将φ(n)拆解成x*k+y,假设x为满足方程最小的值且x>y>0,  x*k <φ(n) ,

ax*k+y≡ 1 mod( n )

a≡ 1 mod( n )

ax*k*ay≡ 1 mod( n )

ay≡ 1 mod( n )

那么存在更小的y,矛盾

最后因为数很大1010*1010 就会爆掉long long,乘法改用龟速乘及时取模防止溢出

时间复杂度为O(√u) umax=(9*2*109)/d = (1.8 * 1010)/d,d最小为2 约为1010 

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e4;
 5 ll L;
 6 int n;
 7 ll gcd(ll a, ll b){return b?(b,a%b):a;}
 8 ll get_phi(ll x){
 9     ll res=x;
10     for(ll i=2;i*i<=x;i++){
11         if(x%i==0){
12             res=res/i*(i-1);
13             while(x%i==0) x/=i;
14         }
15     }
16     if(x>1) res=res/x*(x-1);
17     return res;
18 }
19 ll qmul(ll a, ll k, ll p){
20     ll res=0;
21     while(k){
22         if(k&1) res=(res+a)%p;
23         a=(a+a)%p;
24         k>>=1;
25     }
26     return res;
27 }
28 ll qmi(ll a,ll k ,ll p){
29     ll res=1;
30     while(k){
31         if(k&1) res=qmul(res,a,p);//会爆long long
32         a=qmul(a,a,p);//会爆long long
33         k>>=1;
34     }
35     return res;
36 }
37 int main(){
38     while(scanf("%lld",&L),L){
39             printf("Case %d: ",++n);
40             ll d=gcd(L,8);
41             ll u=L/d*9;
42             if(gcd(u,10)!=1) {printf("0");return 0;}
43             ll phi=get_phi(u);
44             ll ans=1e18;
45             for(ll i=1;i<=phi/i;i++){
46                 if(phi % i==0){
47                     if(qmi(10,i,u)==1) ans=min(ans,i);
48                     if(qmi(10,phi/i,u)==1) ans=min(ans,phi/i);
49                 }
50             }
51             printf("%lld
",ans);
52     }
53 }
原文地址:https://www.cnblogs.com/hhyx/p/12640087.html