我是靠谱客的博主 妩媚西牛,最近开发中收集的这篇文章主要介绍HDU 5728 PowMod 欧拉函数公式推导+欧拉降幂,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 题意
    • 题解

题意

k = ∑ i = 1 m ϕ ( n × i )    m o d    1 0 9 + 7 k=sum_{i=1}^{m}phi(ntimes i) mod 10^9+7 k=i=1mϕ(n×i)  mod  109+7,求 k k k k k k . . . . . .   m o d   p k^{k^{k^{k^{k^k......}}}} mod p kkkkkk...... mod p.
n , m , p ≤ 1 0 7 n,m,pleq 10^7 n,m,p107.

题解

首先计算 k k k.根据下面的公式可以得到递归公式.

function<ll(ll,ll)> dfs=[&](ll n,ll m) {
  return !m?0:n==1?sum[m]:(phi[p[n]]*dfs(n/p[n],m)%mod+dfs(n,m/p[n]))%mod;
};

在这之前用线性筛欧拉函数辅助便可完成,其中 p n p_n pn表示 n n n最小的质因子,可以在线性筛中顺便完成.
接下来计算模 p p p的余数.
由欧拉降幂公式可知,假设原式为 a n s ans ans,则 a n s ans ans无限大,因此在 g c d ( k , p ) ≠ 1 gcd(k,p)neq1 gcd(k,p)=1时,一定满足 b > ϕ ( p ) b>phi(p) b>ϕ(p)的条件,从而原式 = k a n s   m o d   ϕ ( p ) + ϕ ( p )   m o d   p =k^{ans mod phi(p)+phi(p)} mod p =kans mod ϕ(p)+ϕ(p) mod p.
而对于 k , p k,p k,p互质的情况,再加一遍 ϕ ( p ) phi(p) ϕ(p)不影响答案,因此全部的情况都可以转化为一种可能.
那么我们采用递归的方法.
对于上面的 a n s   m o d   ϕ ( p ) ans mod phi(p) ans mod ϕ(p),再取出一个 k k k,那么模数变成 ϕ ( ϕ ( p ) ) phi(phi(p)) ϕ(ϕ(p)),反复嵌套欧拉函数之后不超过 l o g ( p ) log(p) log(p)次模数就会变成 1 1 1.
再嵌套一次快速幂,我们就解决了这题.

#include<bits/stdc++.h> //Ithea Myse Valgulious
using namespace std;
const int yuzu=1e7,mod=1e9+7;
typedef int fuko[yuzu|10];
fuko p,pr,phi,id,sum;
int main() {
  auto gphi=[&](int n) {
    int i,j;
    p[1]=phi[1]=1;
    for (i=2;i<=n;++i) {
      if (!p[i]) pr[++*pr]=p[i]=i,phi[i]=i-1;
      for (j=1;j<=*pr&&pr[j]*i<=n;++j) {
        p[pr[j]*i]=pr[j];
        if (i%pr[j]==0) {
          phi[pr[j]*i]=pr[j]*phi[i];
          break;
        }
        phi[pr[j]*i]=(pr[j]-1)*phi[i];
      }
    }
    for (i=1;i<=n;++i) sum[i]=(sum[i-1]+phi[i])%mod;
    return;
  };
  function<ll(ll,ll)> dfs=[&](ll n,ll m) {
    return !m?0:n==1?sum[m]:(phi[p[n]]*dfs(n/p[n],m)%mod+dfs(n,m/p[n]))%mod;
  };
  auto kasumi=[&](ll a,ll b,ll p) {
    ll zw=1;
    for (;b;b>>=1,a=a*a%p) if (b&1) zw=zw*a%p;
    return zw;
  };
  function<ll(ll,ll)> cal=[&](ll n,ll p) {
    return p==1?1:kasumi(n,cal(n,phi[p])+phi[p],p);
  };
  gphi(yuzu);
  ll n,m,p,k;
  for (;read(n),read(m),read(p);) {
    k=dfs(n,m);
    printf("%lldn",cal(k,p)%p);
  }
}

最后

以上就是妩媚西牛为你收集整理的HDU 5728 PowMod 欧拉函数公式推导+欧拉降幂的全部内容,希望文章能够帮你解决HDU 5728 PowMod 欧拉函数公式推导+欧拉降幂所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(32)

评论列表共有 0 条评论

立即
投稿
返回
顶部