ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-07-22 22:34:47  阅读:171  来源: 互联网

标签:PowMod 5728 return int ll phi pcnt HDOJ mod


参考 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有