其他分享
首页 > 其他分享> > 【HDOJ 5728】PowMod 欧拉定理+递归

【HDOJ 5728】PowMod 欧拉定理+递归

作者:互联网

参考 https://blog.csdn.net/wust_zzwh/article/details/51966450

题目链接

https://acm.hdu.edu.cn/showproblem.php?pid=5728

思路

本题的过程分为两部分:求k,和求k无限次方对p取模。

求k

经分析知,这是无论如何不能直接暴力求解的
假设p为n的因子之一(由题意知,p的个数肯定是1个)

第一行:分类可以得到
第二行:左边,提出公共因子\(\phi[p]\);右边,容易发现n里面必然存在p这个因子,由欧拉函数性质,\(\phi[p*p]=p(p-1)\),可以直接提出p来
第三行:对于质数p,\(\phi[p]+1=p\)
第四行:展开括号
然后发现前面两项可以合并
原式可以写成 $ \ k=f(n,m)= \phi[p]*f(n/p,m)+f(n,m/p) \ \ $ ,就可求出k

k的无限次方

欧拉定理内容:
\(当b>\phi[m]时\),
$ a^b \ mod \ p = a^{b \ mod \ \phi[m]+\phi[m] } \ mod \ p $

根据欧拉定理,可以对指数进行降幂
而又可以递归地求出指数:只需每次把 m 变成 \(\phi[m]\)

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 10000005,mod = 1e9+7;
int t;
int n,m,pp,nn;
bool vis[N];
int cnt;
int p[N],phi[N];
ll pre[N];
int pcnt,prime[N];

void phi_init(int N){
	memset(vis,0,sizeof(vis));
	cnt=0;
    pre[1]=1;
	for(int i=2;i<=N;i++){
		if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
		for(int j=1;j<=cnt&&i*p[j]<=N;j++){
			vis[i*p[j]]=1;
			if(i%p[j]==0){
				phi[i*p[j]]=p[j]*phi[i];
				break;	
			}
			phi[i*p[j]]=(p[j]-1)*phi[i];  //Euler函数是积性函数 
		}
        pre[i]=(pre[i-1]+phi[i])%mod;
	}
}

void func(int n){
    pcnt=0;
    ll N=n;
    for(int i=1;p[i]*p[i]<=N;i++){
        if(p[i]>n) break;
        if(n%p[i]==0){
            prime[++pcnt]=p[i];
            n/=p[i];
        }
    }
    if(n>1) prime[++pcnt]=n;
}

ll f(int id,int n,int m){
    if(m==0) return 0;
    if(n==1) return pre[m];
    int p=prime[id];
    return (phi[p]*f(id-1,n/p,m)%mod+f(id,n,m/p))%mod;
}

ll qPow(ll a,ll b,ll mod){
	ll ans=1;
	while(b){
		if(b%2){
			ans*=a;
			ans%=mod; 
		}
		a*=a;
		a%=mod;  //注意这里也需要取模 
		b/=2;
	}
	return ans+mod;
}

ll solve(ll base,ll mod){
    if(mod==1) return 1;
    ll up=solve(base,phi[mod]);
    return qPow(base,up,mod);
}

int main(){
    phi_init(1e7);
    while(scanf("%d%d%d",&n,&m,&pp)==3){
        func(n);
        ll k=f(pcnt,n,m);
        printf("%lld\n",solve(k,pp)%pp);
    }
    system("pause");
    return 0;
}

标签:PowMod,5728,return,int,ll,phi,pcnt,HDOJ,mod
来源: https://www.cnblogs.com/re0acm/p/16508142.html