[上帝与集合的正确用法]
P4139
上帝与集合的正确用法
题目描述
定义\(a_0 \ = \ 1\) , \(a_n \ = \ 2^{a_{n-1}}\) , 可以证明\(b_n \ = \ a_n \ (mod \ p)\) 在某项之后都是同一个值,求这个值
做法
令\(f(p)=2^{2^{2^{.^{..}}}} \ mod \ p\),当\(b > \phi(p)\)时有欧拉降幂公式:\(a^b \ ≡ \ a^{(b \ mod \ \phi(p)) \ + \ \phi(p)} \ (mod \ p)\)
既\(f(p)=2^{2^{2^{.^{..}}}} \ mod \ p \ , \ f(\phi(p))=2^{2^{2^{.^{..}}}} \ mod \ \phi(p)\)(将 \(p\) 替换为 \(\phi(p)\) 代入\(f(p)\))
故\(f(p)=2^{f(\phi(p)+\phi(p)} \ mod \ p\) ,时间复杂度为 \(p\) 一直进行 \(\phi(p)\) 操作,直到 \(\phi(1) = 0\)
根据唯一分解定理,\(p=p_1^{k_1}×p_2^{k_2}×p_3^{k_3}...×p_n^{k_n},p_i为质数\) , \(\phi(p)=p×(1-\frac{1}{p_1})×(1-\frac{1}{p_2})×(1-\frac{1}{p_3})...×(1-\frac{1}{p_n})\),\(\phi(\phi(p))≤\frac{1}{2}p\),故复杂度为\(log(p)\)级别
code
#include <cstdio>
#include <iostream>
typedef long long LL;
using namespace std;
const int maxn = 1e7+6;
int phi[maxn],prime[maxn],cnt;
bool check[maxn];
int quickpower(LL a,int b,int p)
{
LL res = 1;
while(b)
{
if(b & 1)
res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
int f(int p)
{
if(p == 1) return 0;
return quickpower(2,f(phi[p])+phi[p],p);
}
int main()
{
int T;
scanf("%d",&T);
for(int i=2;i<=maxn;i++)
{
if(!check[i])
{
phi[i] = i - 1;
prime[++cnt] = i;
}
for(int j=1;j<=cnt;j++)
{
if(prime[j] * i > maxn) break;
check[i*prime[j]] = 1;
if(!(i%prime[j]))
{
phi[i*prime[j]] = prime[j] * phi[i];
break;
}
else phi[i*prime[j]] = phi[i] * phi[prime[j]];
}
}
while(T --)
{
int p;
scanf("%d",&p);
printf("%d\n",f(p));
}
return 0;
}