费马小定理和欧拉定理
费马小定理和欧拉定理
1.费马小定理
1)定义
我们现在设正整数
2)证明
我们设一个完全剩余系
消去就可得
2.欧拉定理
1)欧拉函数
欧拉函数记为
其中x为n的质因数个数,而
欧拉函数是积性函数,由它的意义我们可以很容易用乘法原理证明,同时显然可以知道这不是完全积性函数
若
我们可以根据定义得到如果n为素数,则
void getEuler(int x){
eul[1]=1;
for(int i=2;i<=x;i++){
if(!eul[i]){
pri[++tot]=i;
eul[i]=i-1;
}
for(int j=1;j<=tot and i*pri[j]<=x;j++){
if(!(i%pri[j])){
eul[i*pri[j]]=eul[i]*pri[j];
break;
}
eul[i*pri[j]]=eul[i]*(pri[j]-1);
}
}
}
2)定义
现在我们来引入欧拉定理,实际上欧拉定理就是费马小定理的推广在m为素数时显然就是费马小定理
我们先定义两个互质的正整数
3)证明
我们令
消去可得
所以
3.如何食用欧拉定理和费马小定理
1)数学问题
我们可以看这么一道题
例题:
2)信息学
我们来看一道神奇的题
欧拉心算
给出一个正整数
思路:
显然我们暴力是过不了的我们要考虑
我们肯定要推式子,所以直接拿那个题目的式子来推
其中
这样我们就可以推出原式为
所以我们可以用线性筛筛出欧拉函数然后我们再求一次前缀和
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int tot,n,pri[10000001];
long long eul[10000001];
inline int rd(){
register int x=0,y=1;register char c=getchar();
while(c<'0' or c>'9'){
if(c=='-')y=-1;
c=getchar();
}
while(c>='0' and c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*y;
}
void getEuler(int x){
eul[1]=1;
for(int i=2;i<=x;i++){
if(!eul[i]){
pri[++tot]=i;
eul[i]=i-1;
}
for(int j=1;j<=tot and i*pri[j]<=x;j++){
if(!(i%pri[j])){
eul[i*pri[j]]=eul[i]*pri[j];
break;
}
eul[i*pri[j]]=eul[i]*(pri[j]-1);
}
}
for(int i=2;i<=x;i++)eul[i]+=eul[i-1];
}
long long solve(int x){
long long ret=0;int nxt;
for(int i=1;i<=x;i=nxt+1){
nxt=x/(x/i);
ret+=(eul[nxt]-eul[i-1])*eul[x/i]*2-(eul[nxt]-eul[i-1]);
}
return ret;
}
int main(){
n=rd();
getEuler(10000000);
while(n--){
int x=rd();
printf("%lld\n",solve(x));
}
return 0;
}