题解 P4139 上帝与集合的正确用法

Posted colazcy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P4139 上帝与集合的正确用法相关的知识,希望对你有一定的参考价值。

Solution 上帝与集合的正确用法

题目大意:求(2^{2^{2^{2^{ldots}}}}mod;p)

扩展欧拉定理


首先主角扩展欧拉定理:

[a^b equiv egin{cases} a^{b;mod;phi(p)} & gcd(a,p)=1 \ a^b & gcd(a,b) eq 1,b < phi(p) \ a^{b;mod;phi(p) + phi(p)} & gcd(a,b) eq1,b geq phi(p)end{cases} quad mod ; p]

然后既然用到了欧拉函数,我们可以用线性筛来求

首先如果(p)是质数,(phi(p)=p-1)

如果有(n)的最小质因子(p),设(n'= frac{n}{p})(p mid n'),那么有(phi(n)=p imes phi(n')) (如果(n)除掉一个质因子(p)(n')还有质因子(p)那么(n')的质因子集合就是(n)的质因子集合,结合欧拉函数的定义式即可)

(n)的质因子集合为({p_1,p_2,p_3 ldots, p_k}),定义(phi(n)=n imes prod_{i=1}^{k}frac{p_i-1}{p_i})(数学归纳法易证)

如果(p mid n'),那么(n,n')互质,(p)又是质数,积性函数性质(phi(n)=phi(p) imesphi(n'))

然后(2^{2^{2^{2^{ldots}}}})这玩意儿显然(>phi(p)),不断递归求解,模数为(1)时返回(0)即可

注意(phi(1)=1)

#include <cstdio>
using namespace std;
typedef long long ll;
const int maxm = 1e7 + 100;
int vis[maxm],pri[maxm],phi[maxm],pri_tot;
inline void eular(){
    phi[1] = 1;
    for(int i = 2;i < maxm;i++){
        if(!vis[i]){
            pri[++pri_tot] = i;
            phi[i] = i - 1;
        }
        for(int j = 1;j <= pri_tot;j++){
            if(1ll * i * pri[j] >= maxm)break;
            vis[i * pri[j]] = 1;
            if(i % pri[j])phi[i * pri[j]] = phi[i] * (pri[j] - 1);
            else{
                phi[i * pri[j]] = phi[i] * pri[j];
                break;
            }
        }
    }
}
inline ll qpow(ll a,ll b,ll mod){
    a %= mod;
    ll base = a,res = 1;
    while(b){
        if(b & 1)res = (res * base) % mod;
        base = (base * base) % mod;
        b >>= 1;
    }
    return res;
}
inline ll solve(ll mod){
    return mod == 1 ? 0 : qpow(2,solve(phi[mod]) + phi[mod],mod);
}
int t,p;
int main(){
    eular();
    scanf("%d",&t);
    while(t--)scanf("%d",&p),printf("%lld
",solve(p));
    return 0;
}

以上是关于题解 P4139 上帝与集合的正确用法的主要内容,如果未能解决你的问题,请参考以下文章

P4139 上帝与集合的正确用法

洛谷 P4139 上帝与集合的正确用法

题解上帝与集合的正确用法

BZOJ3884: 上帝与集合的正确用法

BZOJ 3884 上帝与集合的正确用法

BZOJ3884 上帝与集合的正确用法 欧拉定理