链接
http://www.lydsy.com/JudgeOnline/problem.php?id=3884
题解
做法一:
显然用欧拉定理+中国剩余定理。
令
a=222222222...
那么显然
ans=2a mod p
如果 p 和
直接递归求解即可。
但如果不互质呢?
那就把 p 分解成
最后得到递推式
令
ans(p)=ans(ϕ(t))×2x×[(2x)ϕ(t)−1 mod t] mod p
做法二:
经大佬 will7101 点拨,我得知一个重要事实:
ab mod p=ab mod ϕ(p) + ϕ(p) mod p
条件是 b>=ϕ(p)
直接递归求解即可。
代码
//欧拉定理+中国剩余定理
#include <cstdio>
#include <algorithm>
#define maxn 10000001
#define ll long long
using namespace std;
int M, phi[maxn];
ll fastpow(ll a, ll b, ll p)
{
ll ans, t;
for(ans=1,t=a;b;b>>=1,t=t*t%p)if(b&1)ans=ans*t%p;
return ans;
}
void init()
{
int i, j;
for(i=1;i<maxn;i++)phi[i]=i;
for(i=2;i<maxn;i++)if(phi[i]==i)for(j=i;j<maxn;j+=i)phi[j]=phi[j]/i*(i-1);
}
ll dfs(ll p)
{
if(p==1)return 0;
ll x=1, t=p, ans;
while(~t&1)t>>=1,x<<=1;
ans=fastpow(2,dfs(phi[t]),t);
ans=ans*x%p*fastpow(x,phi[t]-1,t)%p;
return ans;
}
int main()
{
ll T, p;
init();
for(scanf("%lld",&T);T;T--)
{
scanf("%lld",&p);
printf("%lld\n",dfs(p));
}
return 0;
}
//神奇定理
#include <cstdio>
#include <algorithm>
#define ll long long
#define maxn 10000001
using namespace std;
int phi[maxn];
void init()
{
int i, j;
for(i=1;i<maxn;i++)phi[i]=i;
for(i=2;i<maxn;i++)if(phi[i]==i)for(j=i;j<maxn;j+=i)phi[j]=phi[j]/i*(i-1);
}
ll fastpow(ll a, ll b, ll p)
{
ll t, ans;
for(ans=1,t=a;b;b>>=1,t=t*t%p)if(b&1)ans=ans*t%p;
return ans;
}
ll f(ll p)
{
if(p<=2)return 0;
return fastpow(2,f(phi[p])+phi[p],p);
}
int main()
{
int T, p;
init();
for(scanf("%d",&T);T;T--)
{
scanf("%d",&p);
printf("%lld\n",f(p));
}
return 0;
}