主要用于求a^b%mod,b非常大的时候
欧拉降幂:
求一个数的欧拉函数:
ll phi(ll n)
{
ll i,rea=n;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea-rea/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
rea=rea-rea/n;
return rea;
}
欧拉函数打表:
void euler_table()
{
memset(euler,0,sizeof euler);
euler[1]=1;
for(int i=2;i<maxn;i++)
if(!euler[i]){
for(int j=i;j<maxn;j+=i)///与素数筛类似
{
if(!euler[j])
euler[j]=j;
euler[j]=euler[j]/i*(i-1);
}
}
}
然后与快速幂一起配合使用,快速幂:
ll quickpow(ll x,ll y,ll z)
{
ll ans=1;
while(y)
{
if(y&1)
ans=ans*x%z;
x=x*x%z;
y>>=1;
}
return ans;
}
例题:https://ac.nowcoder.com/acm/contest/330/E
分析:直接分析可得结果为2的n次幂,但n非常大,故要用欧拉降幂
Ac code:
#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
char n[1000006],m[1000005];
ll quickpow(ll x,ll y,ll z)
{
ll ans=1;
while(y)
{
if(y&1)
ans=ans*x%z;
x=x*x%z;
y>>=1;
}
return ans;
}
ll phi(ll n)
{
ll i,rea=n;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea-rea/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
rea=rea-rea/n;
return rea;
}
int main()
{
while(scanf("%s%s",n,m)!=EOF)
{
ll len=strlen(n);
ll p=phi(mod);
ll ans=0;
for(ll i=0;i<len;i++)
ans=(ans*10+n[i]-'0')%p;
ans+=p;
printf("%lld\n",quickpow(2,ans,mod));
}
return 0;
}