POJ3696:The Luckiest number

Description

Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his own lucky number L. Now he wants to construct his luckiest number which is the minimum among all positive integers that are a multiple of L and consist of only digit '8'.

Input

The input consists of multiple test cases. Each test case contains exactly one line containing L(1 ≤ L ≤ 2,000,000,000).

The last test case is followed by a line containing a zero.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the length of Bob's luckiest number. If Bob can't construct his luckiest number, print a zero.

Sample Input

8
11
16
0

Sample Output

Case 1: 1
Case 2: 2
Case 3: 0
这又是一道神题做了我一个上午。。。
需要这些前置技能点:
  1. φ(n)=n*(p1-1)/p1*(p2-1)/p2*...*(pk-1)/pk,证明很简单大家问度娘
  2. 费马小定理,欧拉定理

首先推柿子:
8*11111111...(x个1)=8*(10x-1)/9

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

==   8*(10x-1)%9L===0

==   (10x-1)%9L/gcd(L,8)===0

== 10x≡ 1  (mod 9L/gcd(L,8))

然后又有一个容易反证出来的定理:

对于任意互质正整数a,n,满足ax≡   1(mod n)的最小整数解是φ(n)的约数

然后就按步骤做,WA了Discuss里有测试数据,在算快速幂时候会爆unsigned long long 。。。汗,得优化乘法运算

  代码如下:

//by_MT_LI
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; typedef unsigned long long ll; ll phi(ll n) { ll ans=n; for(ll i=2;i*i<=n;i++) if(n%i==0) { ans=ans/i*(i-1); while(n%i==0)n/=i; } if(n>1)ans=ans/n*(n-1); return ans; } ll n; ll gcd(ll a,ll b) { if(a==0)return b; return gcd(b%a,a); } ll multiplicative(ll a,ll b,ll c) { ll ans=0ll; while(b) { if(b%2==1)ans=(ans+a)%c; b/=2;a=(a+a)%c; } ans%=c; return ans; } ll pow_mod(ll a,ll b,ll mod) { ll ans=1ll; while(b) { if(b%2==1)ans=multiplicative(ans,a,mod); a=multiplicative(a,a,mod);b/=2; } return ans%mod; } int main() { int Case=0; // printf("%lld\n",pow_mod(10, 116194320,8888888889)); while(scanf("%lld",&n)!=EOF&&n) { printf("Case %d: ",++Case); ll m=n*9ll/gcd(n,8); bool bk=false;ll ans=1ll<<63; ll PH=phi(m); for(ll i=1;i*i<=PH;i++) { if(PH%i==0) { if(pow_mod(10,i,m)==1ll) { ans=i;bk=true; break; } if(pow_mod(10,PH/i,m)==1ll) { ans=min(ans,PH/i); bk=true; } } } if(bk==false)printf("0\n"); else printf("%lld\n",ans); } return 0; }

 

posted @ 2018-07-21 16:24  MT_LI  阅读(269)  评论(0编辑  收藏  举报