zoukankan      html  css  js  c++  java
  • [BZOJ3884] 上帝与集合的正确用法 (欧拉函数)

    题目链接:  https://www.lydsy.com/JudgeOnline/problem.php?id=3884

    题目大意:

    给出 M, 求 $2^{2^{2^{2^{...}}}}$ % M 的值. p ≤ 1e9

    题解:

    我们设 M = $2^k$*p , p是奇数

    $2^{2^{2^{2^{...}}}}$ % M =  $2^k$ * ($2^{2^{2^{2^{...}}}-k}$ % p)

    因为p是奇数,所以p与2互质,我们可以用欧拉定理

    原式化为

    可以递归地做下去

    但模数变成1的时候直接返回0就好了

    参考某大佬博客的时间复杂度:

    AC代码如下:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    
    int T;
    inline int read()
    {
        char ch=getchar();
        int s=0,f=1;
        while (!(ch>='0'&&ch<='9')) {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    int qpow(ll a,int b,int m)
    {
        ll res=1;
        for (;b;b>>=1,a=a*a%m) if (b&1) res=res*a%m;
        return res%m;
    }
    int phi(int x)
    {
        int res=x;
        for (int i=2;i*i<=x;i++)
        {
            if (x%i) continue;
            res/=i;res*=i-1;
            while (x%i==0) x/=i;
        }
        if (x>1) res/=x,res*=x-1;
        return res;
    }
    int solve(int p)
    {
        if (p==1) return 0;
        int k=0;
        while (~p&1) p>>=1,k++;
        int phi_p=phi(p);
        int re=solve(phi_p);
        re=(re+phi_p-k%phi_p)%phi_p;
        re=qpow(2,re,p);
        return re<<k;
    }
    int main()
    {
        T=read();
        while (T--)
        {
            int p=read();
            printf("%d
    ",solve(p));
        }    
        return 0;
    }
  • 相关阅读:
    Hello World基于.net framework中CLR的执行
    MVN常用命令
    Git常用命令
    Markdown常用语法
    计算机专用英语词汇
    Windows DiskPart
    字符集过滤器
    SSHkey
    书名
    redis
  • 原文地址:https://www.cnblogs.com/xxzh/p/9534627.html
Copyright © 2011-2022 走看看