费马定理与欧拉定理

费马定理在数论中推理其他结论还是会经常用到了,欧拉定理可以单独出题。欧拉定理其实也算是包含了费马定理,或者说费马定理是欧拉定理中的一种特殊情况。

费马小定理

设 p 是素数, a 是任意整数且 a ≢ 0 ( m o d    p ) ,   则 a p − 1 ≡ 1 ( m o d    p ) 设p是素数,a是任意整数且a\not \equiv0(mod\ \ p),\ \ 则\\ a^{p-1}\equiv 1 (mod\ \ p) p是素数,a是任意整数且a0(mod  p),  ap11(mod  p)

欧拉函数

在1与m之间且与m互素的整数的个数被称为欧拉函数,记为φ(m)

m = p 1 a 1 p 2 a 2 . . . p n a n m = p_1^{a_1}p_2^{a_2}...p_n^{a_n} m=p1a1p2a2...pnan
与点m互素的个数是m减去m的约数以及约数的倍数

但是这些倍数会有重合的一部分,这些重合的部分要加上,但是加上的这些有一部分仍然是重合与其他区块的。

根据容斥原理
m − m p 1 − m p 2 − . . . + m p 1 p 2 + . . . − m p 1 p 2 p 3 − . . . m - \frac{m}{p_1} - \frac{m}{p_2}-...+ \frac{m}{p_1p_2}+... - \frac{m}{p_1p_2p_3}-... mp1mp2m...+p1p2m+...p1p2p3m...
我们可以发现
m ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p n ) m(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1 - \frac{1}{p_n}) m(1p11)(1p21)...(1pn1)
的展开式为上式

C++

#include <iostream>

using namespace std;

int solve(int m)
{
    int res = m;
    for (int i = 2; i <= m / i + 1; i++)
    {
        if (m % i == 0)
        {
            res = res / i * (i - 1);
            while (m % i == 0) m /= i;
        }
    }
    if (m > 1) res = res / m * (m - 1);
    return res;
}

int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int m;
        cin >> m;
        cout << solve(m) << endl;
    }
    return 0;
}

欧拉筛求欧拉函数

代码如下讲解在代码后面

C++

#include <iostream>

using namespace std;

const int N = 1e6 + 10;

int prime[N], cnt;
bool st[N];
int euler[N];

void get_eulers(int n)
{
	euler[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		if (!st[i])
		{
			prime[cnt++] = i;
			euler[i] = i - 1; // 如果i为质数,其欧拉函数为i - 1
		}
		for (int j = 0; prime[j] <= n / i; j++)
		{
			st[prime[j] * i] = true;
			if (i % prime[j] == 0)
			{
				euler[prime[j] * i] = prime[j] * euler[i];
				break;
			}
			euler[prime[j] * i] = euler[i] * (prime[j] - 1);
            // euler[prime[j] * i] = prime[j] * euler[i] * (1 - 1 / prime[j]);
		}
	}
}

int main()
{
	int n;
	cin >> n;
	get_eulers(n);
	long long res = 0;
	for (int i = 1; i <= n; i++)
	{
		res += euler[i];
	}
	cout << res << endl;
	return 0;
}

当一个数n是质数时,其欧拉函数为n-1


i%prime[j]==0时,说明i可以用prime[j]表示出来,根据求解欧拉函数的公式

一个数的欧拉函数只与其所有公约数的大小以及这个数本身的大小有关,与公约数的幂次无关。由于i%prime[j]==0i的公约数能表示出prime[j],因此prime[j] * i的欧拉函数与i的关系为相差prime[j]

此时 euler[prime[j] * i] = euler[i] * prime[j]


其他情况下,i不能表示出prime[j],那么在求prime[j] * i的欧拉函数不仅要乘上prime[j],而且要在公式最后面乘上

(1-1/prime[j])

前后新乘上的两部分可以合并转换为(prime[j] - 1)

i * prime[j]的欧拉函数为euler[prime[j] * i] = euler[i] * (prime[j] - 1)


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值