欧拉降幂板子--2019-icpc南昌网络赛b

时间:2019-09-24
本文章向大家介绍欧拉降幂板子--2019-icpc南昌网络赛b,主要包括欧拉降幂板子--2019-icpc南昌网络赛b使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意

给a,b,p。有b个a的幂
\[ a^{a^{a^{a...}}} \]
欧拉降幂板子

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <iomanip>
#include <cstdio>

using namespace std;
typedef long long LL;
typedef pair<double, double> PDD;
typedef pair<LL, LL> PLL;

const LL N = 1e6+50;
const LL MOD = 1e9+7;
const LL INF = 0x3f3f3f3f;

#define lson l, m, rt>>1
#define rson m+1, r, rt>>1|1

LL phi[N], vis[N], prime[N], cnt;
void Euler()
{
    for(LL i = 2;i < N;++i)
    {
        if(!vis[i])
        {
            prime[cnt++] = i;
            phi[i] = i-1;
        }
        for(int j = 0;j < cnt && i*prime[j] < N;++j)
        {
            vis[i*prime[j]] = 1;
            if(i%prime[j] == 0)
            {
                phi[i*prime[j]] = phi[i]*prime[j];
                break;
            }
            phi[i*prime[j]] = phi[i]*(prime[j]-1);
        }
    }
    phi[1] = 1;
}

LL q_pow(LL a, LL b, LL p)
{
    LL ret = 1;
    while(b)
    {
        if(b&1) ret = ret*a>p?ret*a%p+p:ret*a;
        b >>= 1;
        a = a*a>p?a*a%p+p:a*a;
    }
    return ret;
}

LL solve(LL a, LL b, LL m)
{
    if(m == 1 || b == 0) return 1;//phi(m) < m,所以最后m为1
    return q_pow(a, solve(a, b-1, phi[m]), m);
}

int main()
{
    Euler();
    int T;scanf("%d", &T);
    while(T--)
    {
        LL a, b, m;
        scanf("%lld%lld%lld", &a, &b, &m);
        printf("%lld\n", solve(a, b, m)%m);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/shuizhidao/p/11578579.html