一、题目

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.首先要根据题意写出一个公式

有了这个公式,我们就可以进行下一步

这样,得出,其中P其实可以发现是可以变为任意大小的整数的,所以直接不用管

这个公式再联系同余式

变形

行吧,不服不行,这里我们也应该非常清楚,该同余方程有解的充分必要条件是gcd(10^x,M) = 1.根据大整数的素数分解,10的素因子只有2,5,所以进一步推出有解的条件为gcd(10,M)=1.

那么我们其实已经分析出了没有x的条件就是gcd(10,M)!=1.

此处结合

欧拉定理:对任何两个互质的正整数a,m(m≥2)有a^φ(m)≡1(mod m).

那么我们也可以得出,当gcd(10,M)=1时,有

推到这里挺不容易的,但更加不幸的是,这并不意味着我们就成功了 - -!

我们要找的是最小的x。这里我们需要知道指数的mod运算是有循环节的。我们假设上面这个欧拉定理公式的循环节长度是r。那么可以推出

再结合一个常识式子

OK,再开动我们的小脑筋,这不就是让我们求满足

算你狠~

接下来就是在M的欧拉函数值的所有因子F中,找到满足上面10^F≡1(mod M)的最小因子F,你就成功了!

对于代码写法,我是先线性打sqrt(MAX)的素数表,然后再算欧拉函数值。时间250ms(我绝对不是二百五..)。

三、AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+3;
bool isPrime[MAXN];
int Prime[MAXN], nPrime;
LL Factor[MAXN], Cnt; LL Multi(LL a, LL b, LL mod)
{
LL ans = 0;
while(b)
{
if(b&1)
{
ans = (ans + a)%mod;
}
b>>=1;
a = (a+a)%mod;
}
return ans;
} LL Pow(LL a, LL n, LL mod)
{
LL ans = 1;
while(n)
{
if(n&1)
{
ans = Multi(ans, a, mod);
}
n>>=1;
a = Multi(a, a, mod);
}
return ans;
} LL gcd(LL a, LL b)
{
return b==0?a:gcd(b, a%b);
} void getPrime() //线筛素数
{
memset(isPrime, 1, sizeof(isPrime));
isPrime[0] = isPrime[1] = 0;
nPrime = 0;
for(int i = 2; i < MAXN; i++)
{
if(isPrime[i])
{
Prime[nPrime++] = i;
}
for(int j = 0; j < nPrime && (LL)i*Prime[j] < MAXN ; j++)
{
isPrime[ i*Prime[j] ] = 0;
if(i%Prime[j])
break;
}
}
} LL Euler(LL N)
{
LL Phi = N;
for(int i = 0; Prime[i]*Prime[i] <= N; i++)
{
if(N%Prime[i] == 0)
{
Phi = Phi - Phi/Prime[i];
do
{
N/=Prime[i];
}while(N%Prime[i] == 0);
}
}
if(N>1)
Phi = Phi - Phi/N;
return Phi;
} LL solve(LL N)
{
LL M = N/gcd(N, 8)*9;
if(gcd(10, M) != 1)
{
return 0;
}
LL Phi = Euler(M);
Cnt = 0;
for(LL i = 1; i*i < Phi; i++)
{
if(Phi%i == 0)
{
Factor[Cnt++] = i;
Factor[Cnt++] = Phi/i;
}
}
sort(Factor, Factor+Cnt);
for(LL i = 0; i < Cnt; i++)
{
if(Pow(10, Factor[i], M) == 1)
return Factor[i];
}
return 0;
} int main()
{
LL N;
int cnt = 0;
getPrime();
while(scanf("%I64d", &N) && N)
{
cnt++;
printf("Case %d: %I64d\n", cnt, solve(N));
}
return 0;
}

  

POJ_3696 The Luckiest number 【欧拉定理+同余式+对取模的理解】的更多相关文章

  1. hdu 5109(构造数+对取模的理解程度)

    Alexandra and A*B Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  2. C#取模的理解:为什么当a<b,a%b=a?

    一,取模a%b 1,如果a>b,例如10%7=3,这是什么原因呢?可以根据下面的理解 10 =7*1+3,则模就是3 2,如果a<b,例如7%10 = 7,这时怎么得到的呢?根据下面来理解 ...

  3. POJ3696 The Luckiest Number 欧拉定理

    昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...

  4. BZOJ 3884 欧拉定理 无穷幂取模

    详见PoPoQQQ的博客.. #include <iostream> #include <cstring> #include <cstdio> #include & ...

  5. poj 3696 The Luckiest Number

    The Luckiest Number 题目大意:给你一个int范围内的正整数n,求这样的最小的x,使得:连续的x个8可以被n整除. 注释:如果无解输出0.poj多组数据,第i组数据前面加上Case ...

  6. poj_3696_The Luckiest number

    Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his own ...

  7. HDU 2462 The Luckiest number

    The Luckiest number Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Ori ...

  8. The Luckiest number(hdu2462)

    The Luckiest number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. HDU 1212 Big Number(C++ 大数取模)(java 大数类运用)

    Big Number 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 ——每天在线,欢迎留言谈论. 题目大意: 给你两个数 n1,n2.其中n1 ...

随机推荐

  1. 今天写shader流光效果,shader代码少了个括号,unity shader compiler卡死且不提示原因

    今天写shader流光效果,shader代码少了个括号,unity shader compiler卡死且不提示原因 好在找到了原因,shader 代码如下,原理是提高经过的颜色亮度 void surf ...

  2. Python编写两个数的加减法游戏

    目标: 1.实现两个数的加减法 2.回答者3次输错计算结果后,输出正确结果,并询问回答者是否继续 1.使用常规函数实现两个数的加减法游戏 代码如下: #!/usr/bin/env python # - ...

  3. MySql 获取服务提供的sakila数据库(Example Databases)

    关于这个数据库也就是样例数据库,数据库,数据库,最可怕的就是没有数据了,对吧?没有数据你学个什么呀. 可是,没有数据,咱会自己insert,那只能适用于初学者.对于数据库的优化方面的学习,还是有大数据 ...

  4. dataframe 用法总结

    http://pda.readthedocs.io/en/latest/chp5.html data = [] 列表初始化 data = (,) data = {} 字典初始化 data = pd.D ...

  5. Vue.js组件调用用及其组件通信

    1.需要import,然后components注册.然后如下代码调用. <template> <header></header> //注册后才能这样使用 <b ...

  6. 使用Sqlserver事务发布实现数据同步(转)

    出处:http://www.cnblogs.com/daizhj/archive/2009/11/18/1605293.html 事务的功能在sqlserver中由来已久,因为最近在做一个数据同步方案 ...

  7. 递增三元数组——第九届蓝桥杯C语言B组(省赛)第六题

    原创 标题:递增三元组 给定三个整数数组A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2, ... CN],请你统计有多少个三元组(i, ...

  8. XE中rectangle实现渐变

    Fill -> Kind -> Gradient(选项) -> Gradient(Edit) 添加颜色即可

  9. Docker 镜像的制作和使用

    镜像 Layer(层) 镜像里的内容是按「层」来组织的,「层」可以复用,一个完整的镜像也可以看做是一个「层」.多个「层」叠加在一起就形成了一个新的镜像,这个镜像也可以作为别的镜像的基础「层」进行更加复 ...

  10. 进阶Kotlin-常见关键字

    常见Kotlin 的关键字   一些常见的语法,我没有写注释. 前面基础的kotlin语法已经弄完了. 现在是高阶kotlin的语法啊. 包括,面向对象,lambad等. 其中面向对象的三大特点:封装 ...