P1405 苦恼的小明(欧拉降幂)

题目链接:https://www.luogu.com.cn/problem/P1405

思路:

先要知道什么是欧拉定理:如果a,m互质,则a^b %m = a^(b%phi(m) + phi(m) ) %m

然后将每一步都写出来,eg:a^b^c^d

ans = a^(t1 %phi(m) + phi(m) ) %m , p1 = phi(m);

t1 = b^(t2 % phi(p1) + phi(p1) ) % p1 , p2 = phi(p1);

t2 = c^(t3 % phi(p2) + phi(p2) ) % p2 , p3 = phi(p2);

t3 = c^(t4 % phi(p3) + pihi(p3) ) % p3 , p4 = phi(p3);

t4 = d;

所以,可以递归去做,这题与bzoj 3884的解法一样。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6+10;
const ll mod = 10007;
ll a[N];
int n;
ll qpow(ll x,ll y,ll m)
{
    ll res = 1ll;
    while(y)
    {
        if(y&1) res = res*x%m;
        x = x*x%m;
        y >>= 1;
    }
    return res;
}
ll eular(ll x)
{
    ll res = x,tp = (ll)sqrt(1.0*x);
    for(ll i=2;i<=tp;i++)
    {
        if(x%i == 0)
        {
            res = res/i*(i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x>1) res = res/x*(x-1);
    return res;
}
ll f(int id,ll m)
{
    if(id == n) return a[n];
    ll phi = eular(m);
    ll p = f(id+1,phi)%phi +phi;
    return qpow(a[id],p,m);
}
int main(void)
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    ll res = f(1,mod);
    printf("%lld\n",res);
    return 0;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/103822975
今日推荐