HDU 5728 PowMod

来源:互联网 发布:考勤机更改下载数据 编辑:程序博客网 时间:2024/06/08 01:04

解题思路:

首先考虑求k的值,定义sum(m,n)=mi=1(ϕ(in)),当(a,b)=1时,ϕ(ab)=ϕ(a)ϕ(b)为积性函数,对于素数p,
(1):ϕ(pn)=ϕ(pn1)p=ϕ(pn1)(p1)+ϕ(pn1)
(2):ϕ(ap)=ϕ(a)ϕ(p)=ϕ(a)(p1)
再考虑sum(m,n):
sum(m,n)=mi=1,p/iϕ(inp)(p1)+mpiϕ(inp)p
=mi=1,p/iϕ(inp)(p1)+mpiϕ(inp)(p1)+mpiϕ(inp)
=mi=1ϕ(inp)(p1)+mpiϕ(inp)
=mi=1ϕ(inp)(p1)+m/pi=1ϕ(ipnp)
=mi=1ϕ(inp)(p1)+m/pi=1ϕ(n)
(公式好难打T_T,要是打错根据上下文理解一下)
可以发现:sum(m,n)=sum(m,n/p)+sum(m/p,n);可以递归求解
再考虑kkk...k,可以用降幂公式求解。
abmodc=abmodϕ(c)+ϕ(c)(b>=ϕ(c))
当mod=1时结束递归。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<map>#include<string>#include<queue>#include<vector>#include<list>//#pragma comment(linker,"/STACK:1024000000,1024000000")using namespace std;#define INF 0x3f3f3f3fconst int MAXN=10000005;bool check[MAXN+10];int phi[MAXN+10];int prime[MAXN+10];int tot;long long sum[MAXN+10];void phi_and_prime(int N){    memset(check,false ,sizeof check);    phi[1]=1;    tot=0;    for(int i=2;i<=N;i++)    {        if(!check[i])        {                    prime[tot++]=i;            phi[i]=i-1;        }        for(int j=0;j<tot;j++)        {            if(i*prime[j]>N) break;            check[i*prime[j]]=true;            if(i%prime[j]==0)            {                phi[i*prime[j]]=phi[i]*prime[j];                break;            }            else            {                phi[i*prime[j]]=phi[i]*(prime[j]-1);            }        }    }}long long mod=1000000007;long long get(int p,long long n,long long m){    if(n==1) return sum[m];    if(m==0) return 0;    for(int i=p;i<tot&&(long long)prime[i]*prime[i]<=n; i++)    {        if(n%prime[i]==0) return (get(i+1,n/prime[i],m)*(prime[i]-1)%mod+get(i,n,m/prime[i]))%mod;    }    if(n>1) return (get(0,1,m)*(n-1)%mod+get(p,n,m/n))%mod;}long long pow_m(long long a,long long n,long long mod){    long long res=1;    while(n)    {        if(n%2) res*=a,res%=mod;        a=a*a;a%=mod;        n/=2;    }    return res;}long long dfs(long long k,long long mod){    if(mod==1) return 0;    return pow_m(k,dfs(k,phi[mod])+phi[mod],mod);}int n,m,p;int main(){    phi_and_prime(MAXN);    for(int i=1;i<MAXN;i++)        sum[i]=(sum[i-1]+phi[i])%mod;    while(~scanf("%d%d%d",&n,&m,&p))    {        long long k=get(0,n,m);        long long ans=dfs(k,p);        printf("%lld\n",ans);    }    return 0;}
0 0
原创粉丝点击