0.前言
在数论中,欧拉定理(Euler Theorem,也称费马-欧拉定理或欧拉函数定理)是一个关于同余的性质。而欧拉定理的内容为表示为:

而本文将会证明欧拉定理。
1.基本概念
在证明欧拉定理之前需要先了解几个知识点
1.1 质数
质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。在数学界,关于质数的研究非常多,最著名便是哥德巴赫猜想
1.2 公约数
公约数,亦称“公因数”。它是指能同时整除几个整数的数 。如果一个整数同时是几个整数的约数,称这个整数为它们的“公约数”;公约数中最大的称为最大公约数。对任意的若干个正整数,1总是它们的公因数。
最大公约数可记为gcd()或()。
1.3 互质
互质是公约数只有1的两个整数,叫做互质整数。公约数只有1的两个自然数,叫做互质自然数,后者是前者的特殊情形。例如,3与5的公约数只有1,所以它们是互质的。可以记为gcd(3,5)=1.
1.4 同余
同余是数论中的重要概念。给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。
1.5 完全剩余系
命 m 为一个自然数,a,b为整数。如果 为 n 的整数倍,则称 a,b 关于 n 同余,用同余式 a ≡ b(mod m) 记之。否则称a,b关于 n 不同余,记为 a ≢ b(mod m)。我们称 n 为同余式的模(modulus)。同余式满足:
反射性(reflection),即 a ≡ a(mod m);
对称性(symmetry),即由 a ≡ b(mod m)可得 b ≡ a(mod m);
传递性(transitivity),即由 a ≡ b(mod m),b ≡ c (mod m)可得 a ≡ c(mod m)。
因此,可以利用同余关系将整数分类,凡同余的数属于一个类,于是异类中的数皆不同余。共得到整数的 n 个类。在每一个类中各取一个数作为代表所成的集合称为模 n 的一个完全剩余系。
2. 欧拉函数
2.1 定义
欧拉函数是指在数论中,对正整数m,欧拉函数是小于m的正整数中与m互质的数的数目.记为φ(m)。也就是在一组数m的完全剩余系S中,与m互质的数构成的子集,而φ(m)就指这个子集中元素的个数。例如,n=12,S=1,5,7,11,这个集合共有4个元素,那么φ(m)=4.
2.2 通项公式
通项公式为: φ(m)=m(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pm)* 其中p为n的质因子
证明(涉及唯一分解定理):
因为是求与n互质的数的个数,也就是把不与n互质的数给筛掉,那就可得:m-(m/p1)-(m/p2)-(m/p3)-…-(m/pm)。但是,在筛的过程中,有的数可能是多个数的倍数,所以会被多减,而多减的数也就要就回去。例如:一个数既是p1的倍数,又是p2的倍数,这个数就会被多减。根据这个就可得:m-(m/p1)-(m/p2)-(m/p3)-…-(m/pm)+[m/(p1p2)]+[m/(p1p3)]+…+[m/(pm*pk)]。但在加回来之后,可有的数又是3个数的倍数,在刚开始被减了,但在后面又加了回来,所以需要再减一次,可得:m-(m/p1)-(m/p2)-(m/p3)-…-(m/pm)+[m/(p1p2)]+[m/(p1p3)]+…+[m/(pmpk)]-[m/(p1p2p3)]-[m/(p2p3p4)]-[m/(p3p4p5)]-…-[m/(pmpk*pq)],再整理一下可得:φ(m)=m(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pm)*。
代码:
int getphi(int m) {
int ans = m;
for (int i = 2; i * i <= m; i++) {
if (m % i == 0) {
ans = ans / i * (i - 1);
while (m % i == 0) m /= i;
}
}
if (m > 1)
ans = ans / m * (m - 1);
return ans;
}
3. 欧拉定理
3.1 定义
在本文刚开始,便已经提及了欧拉定理,那就是:a^φ(m) ≡ 1 (mod m)。
3.2 证明
我们可以构造一个与m互质的数列,再来进行证明。
设t1,t2,…,tφ(m)为模m意义下的一个简化剩余系,那么at1,at2,…,atφ(m)也是模m意义下的一个简化剩余系。所以t1,t2,…,tφ(m)≡at1,at2,…,atφ(m)≡a^φ(m)t1t2…tφ(m) (mod m),这里可以约掉t1t2…tφ(m),所以a ^ φ(m) ≡ 1 (mod m)。
4.例题
在说了那么多以后,我们来看一下例题:
题目描述
在我国传统文化中,常把数字8认为是幸运的。小明有一个自己幸运数字 ,他想把两者结合起来,构造一个仅由8组成的数字(8,88,888,…),且这个数字是L的倍数。可惜小明解决不了这个复杂的任务,他想麻烦你告诉他这样的数字是否存在?如果存在,这个数字最少是几位数?
输入格式
多组数据,每行一个正整数L(1<=L<=2e9).
最后一行输入0表示结束
输出格式
如果存在满足条件的幸运数字,输出其最小位数;如果不存在输出0。
样例
样例输入
8
11
16
0
样例输出
Case 1: 1
Case 2: 2
Case 3: 0
样例解释
第一个数据,8是8的倍数😋,因此最小长度为1;
第二个数据,8不是11的倍数😫,88是11的倍数😆,因此最小长度为2;
第三个数据,不存在满足要求的幸运数字😭,输出0.
数据范围与提示
对30%的数据,保证每组数据都存在满足条件的最小长度,且所有答案之和不超过10^8;
对50%的数据,保证答案之和不超过10^8;
对70%的数据,L<=10^8;
对100%的数据,L<=2e9.
这道题如果想要得到满分,光看样例的话,暴力是肯定不行的,而正解的话便是用到欧拉定理。而且光是long long的话也是不行的,也是会爆的,所以要用__int128。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll k, m, phi, ans, n;
ll gcd(ll a,ll b) {
return b > 0 ? gcd(b, a%b) : a;
}
ll getphi(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 qkpow(__int128 a, __int128 b) {
ll sum = 1;
while (b) {
if (b & 1)
sum = (sum * a) % m;
a = (a * a) % m;
b >>= 1;
}
return sum % m;
}
ll fun(ll phi, ll m) {
ll ans=0;
for (ll i = 1; i * i <= phi; i++) {
if (phi % i == 0) {
if (qkpow(10, i) % m == 1) {
return i;
}
if (qkpow(10, phi / i) == 1)
ans = phi / i;
}
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
while (cin >> n && n!=0) {
m = 9 * n / (gcd(8, n));
if (gcd(10, m) != 1) {
cout << "Case " << ++k << ": 0" <<endl;
continue;
}
phi = getphi(m);
ans = fun(phi, m);
cout << "Case " << ++k << ": " << ans << endl;
}
}
本文详细介绍了欧拉定理及其证明,并给出了与欧拉定理相关的例题。欧拉定理指出,对于正整数m和a,若a与m互质,则a^φ(m) ≡ 1 (mod m),其中φ(m)是小于m并与m互质的正整数个数。文章首先阐述了质数、公约数、互质、同余和完全剩余系等基础概念,接着定义并探讨了欧拉函数φ(m)的通项公式,最后通过例题展示了欧拉定理在解决问题中的应用。
4797





