[上帝与集合的正确用法]

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;
}
posted @ 2024-02-26 17:31  风丨铃  阅读(2)  评论(0编辑  收藏  举报