BZOJ 3884 上帝与集合的正确用法 (欧拉定理)

题目大意:求2^(2^(2^(2^(2^...)))) mod p的值    

题解:https://blog.csdn.net/popoqqq/article/details/43951401

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long

using namespace std;

void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
    k*=f;
}

ll phi(ll n)
{
    ll rea=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0){
            rea=rea-rea/i;
            do
                n/=i;
            while(n%i==0);
        }
    }
    if(n>1)
        rea=rea-rea/n;
    return rea;
}

ll quick_mod(ll a,ll b,ll c)
{
    ll res,t;
    res=1;
    t=a%c;
    while(b)
    {
        if(b&1){
            res=res*t%c;
        }
        t=t*t%c;
        b>>=1;
    }
    return res;
}

int T;
int p;

int Solve(int p)
{
    if(p==1) return 0;
    int temp=0;
    //p=2^k*q;
    while(~p&1) p>>=1,++temp;//p为提取出来的奇数q,temp为2的多少次方
    int phi_p=phi(p);
    int re=Solve(phi_p);//回溯计算
    (re+=phi_p-temp%phi_p)%=phi_p;
    re=quick_mod(2,re,p)%p;
    return p;
}

int main()
{
    read(T);
    while(T--){
        read(p);
        cout<<Solve(p)<<endl;
    }
    return 0;
}

 

posted @ 2018-10-10 16:53  Somnus、M  阅读(158)  评论(0编辑  收藏  举报