Kattis - exponial
题意:
求
n(n−1)(n−2)⋅⋅⋅
%m。
思路:
欧拉降幂公式。
ab=ab%ϕ(n)+ϕ(n)(mod n)
n<5
时要特判。
代码:
#include<bits/stdc++.h>
#define ll long long
ll phi(ll x) //欧拉函数
{
ll res=1;
for(ll p=2;p*p<=x;++p)
{
if(x%p==0)
{
res*=p-1;
x/=p;
}
while(x%p==0)
{
res*=p;
x/=p;
}
}
if(x>1)
{
res*=x-1;
}
return res;
}
ll _pow(ll a,ll b,ll m) //快速幂 %m
{
ll res=1;
while(b)
{
if(b&1) res=(res*a)%m;
b/=2;
a=(a*a)%m;
}
return res;
}
ll expo_trunc(ll n)
{
return n<4?n<3?n:9:100000;
}
ll solve(ll n,ll m) //降幂公式
{
if(m==1) return 0;
if(n==1) return 1;
ll om=phi(m),e=expo_trunc(n-1);
if(e==100000) e=om+solve(n-1,om);
return _pow(n,e,m);
}
int main()
{
ll n,m;
while(~scanf("%lld %lld",&n,&m))
{
printf("%lld\n",solve(n,m));
}
}