一、题目

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. Python05 函数

    待更新... 2018-4-16 09:00:30

  2. Docker学习笔记_安装和使用Redis

    一.准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:Docker 二.安装过程 1.搜索Redis                         su ...

  3. csv、txt读写及模式介绍

    1读写模式 r以读方式打开文件,可读取文件信息 w已写方式打开文件,可向文件写入信息.如文件存在,则清空,再写入 a以追加模式打开文件,打开文件可指针移至末尾,文件不存在则创建 r+以读写方式打开文件 ...

  4. 开源IMS平台中间件Mobicents

    下面内容来自百度百科 Mobicents 是一个高伸缩性.事件驱动的应用服务器.是一款专业的.开放源代码的 VoIP 中间件平台.Mobicents是首个采用JAIN SLEE标准的开放式源代码电信应 ...

  5. .net Reflection(反射)- 二

    反射 Reflection 中访问方法 新建一个ClassLibrary类库: public class Student { public string Name { get; set; } publ ...

  6. .net Stream篇(七)

    NetworkStream 目录: NetworkStream的作用 简单介绍下TCP/IP 协议和相关层次 简单说明下 TCP和UDP的区别 简单介绍下套接字(Socket)的概念 简单介绍下Tcp ...

  7. query聚类技术

    query聚类 目的 query聚类主要有以下两个目的 解决query空间稀疏问题(长尾query) 挖掘用户意图(一条行为包含的意图是稀疏的,当有一簇行为时,意图更明确) 可以说聚类是构建内容模型的 ...

  8. Android ActionBar仿微信界面

    ActionBar仿微信界面 1.学习了别人的两篇关于ActionBar博客,在结合别人的文章来仿造一下微信的界面: 思路如下:1).利用ActionBar生成界面的头部,在用ActionBar的Ac ...

  9. 手动创建spring项目(maven/IDEA环境)

    1.创建maven项目 按照步骤一步一步来 创建项目 这里选择maven的模板 设置包名 设置项目的maven的配置信息.maven仓库路径(会从maven配置文件中获取) 这里设置项目名.项目保存路 ...

  10. python文件操作-修改文件中的内容

    一.文件读写有缓冲区 fw = open('nhy','w') fw.write('sdfsdf') fw.flush()# 把缓冲区里面的数据立即写到磁盘上 fw.close() 二.with的用法 ...