​传送门:欧拉定理​

假如要我们快速求​​[1--n]​​​和​​n​​互质的个数有多少个,我们可以利用埃氏筛法的思想,把它筛出来,然后统计,但是如果数据过大,无法用数组标记时,我们需要利用欧拉函数求:

欧拉函数

洛谷:5091 欧拉函数+欧拉降幂+大数取模_大数取模

p代表质因数,所以我们可以通过枚举因数,来确定φ(x),证明我不会,但我迟早会的。

代码实现:

ll phi(ll x)//欧拉函数
{
ll res=x;
for(ll i=2; i*i<=x; i++)//枚举因子
{
if(x%i==0)
{
res=res*(i-1)/i;
while(x%i==0)//将相同的质因子,去除
{
x/=i;
}
}
}
if(x>1)res=res*(x-1)/x;
return res;
}

欧拉降幂:

公式:

洛谷:5091 欧拉函数+欧拉降幂+大数取模_大数取模_02

根据这个公式写就没问题了。证明我不会,但我迟早会的。

大数取模:

这个就很简单了,大数用字符串表示,取模就能取的时候就取模就🆗了

ll mod(char *s,ll phim)//大数取模
{
ll n=strlen(s);
ll sum=0;
for(int i=0; i<n; i++)
{
sum=(sum*10+(s[i]-'0'))%phim;
}
return sum;
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e7+5;
char s[maxn];
ll a[maxn];
ll gcd(ll a,ll b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
ll mod(char *s,ll phim)//大数取模
{
ll n=strlen(s);
ll sum=0;
for(int i=0; i<n; i++)
{
sum=(sum*10+(s[i]-'0'))%phim;
}
return sum;
}
ll phi(ll x)//欧拉函数
{
ll res=x;
for(ll i=2; i*i<=x; i++)//枚举因子
{
if(x%i==0)
{
res=res*(i-1)/i;
while(x%i==0)
{
x/=i;
}
}
}
if(x>1)res=res*(x-1)/x;
return res;
}
ll ksm(ll a,ll b,ll m)
{
ll res=1;
while(b)
{
if(b&1)
{
res=res*a%m;
}
b>>=1;
a=(a*a)%m;
}
return res%m;
}
ll Getv(char *s)
{
ll sum=0,n=strlen(s);
for(int i=0; i<n; i++)
{
sum=(sum*10+s[i]-'0');
}
return sum;

}
int main()
{
ll a,b,m;
cin>>a>>m>>s;
ll n=strlen(s);
a%=m;
if(n<=16)
{
cout<<ksm(a,Getv(s),m)<<endl;
}
else if(gcd(a,m)==1)
{
cout<<ksm(a,mod(s,phi(m)),m)<<endl;
}
else
{
cout<<ksm(a,mod(s,phi(m))+phi(m),m)<<endl;
}
}