HDU 5728 PowMod

来源:互联网 发布:淘宝抠图出来衣服 编辑:程序博客网 时间:2024/06/04 19:51

Description
Declare:
k=mi=1φ(in) mod 1000000007
n is a square-free number.
φ is the Euler’s totient function.
find:
ans=kkkk...kmod p
There are infinite number of k

Solution
比赛时候没推出来。。
下面那个很好搞,和BZOJ3884一样咯,递归搞定
关键是上面
首先令sum(n,m)=mi=1φ(in) mod 1000000007
因为φ是积性函数,那么令p为n的一个因数
则可以得到sum(n,m)=φ(p)mi=1φ(in/p)+floor(m/p)i=1φ(in)    ...................(1)
关于上面这个式子的推导:
对于那些和p互质的i , φ(in)=φ(in/p)φ(p)(积性函数的定义咯)
对于那些和p不互质的iφ(in)=φ(in/p)p(欧拉函数的定义,要证明的话可以用剩余系)
p是个素数,则φ(p)=p1,式(1)得证。
于是式(1)可以简化为sum(n,m)=φ(p)sum(n/p,m)+sum(n,floor(m/p))
于是k可以在远小于log次调用递归里得到。

当然,关于之前那个k的无限次方,题解还有更好的方式(不用每次提项了)
题解给出一个公式

ab mod p=aφ(p)+b mod φ(p)

没有欧拉公式的互素的限制!!!

但是好像有其他限制:b>=φ(p),比如这有组反例(2,1,4),当然反例是不满足那个限制的,详情可见知乎
还有证明
然后在这道题里kkkk...k是无限大的,所以可以衣食无忧的用哪个公式。
总之有了这个公式后那个BZOJ3884变成了递归入门题PoPoQQQ大爷,我绝无冒犯您的意思。。
数论还是很(ao)有(miao)意(chong)思(chong)的

Code

#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>using namespace std;const int M=1e7+5;const int P=1e9+7;bool mark[M];int prime[M],phi[M],sum[M],t;inline int Mod(int b){return b>=P?b-P:b;}inline void pret(){    phi[1]=1;    for(int i=2;i<M;++i){        if(!mark[i])prime[t++]=i,phi[i]=i-1;        for(int j=0;j<t&&1ll*prime[j]*i<M;++j){            mark[i*prime[j]]=1;            if(i%prime[j]==0){                phi[i*prime[j]]=phi[i]*prime[j];                break;            }            phi[prime[j]*i]=phi[i]*(prime[j]-1);        }    }    for(int i=1;i<M;++i)        sum[i]=Mod(sum[i-1]+phi[i]);}inline int work(int n,int m){    if(n==1)return sum[m];    if(m==1)return phi[n];    if(m<1)return 0;    for(int i=0;prime[i]*prime[i]<=n;++i){        if(n%prime[i]==0)            return Mod(1ll*phi[prime[i]]*work(n/prime[i],m)%P+work(n,m/prime[i]));    }    return Mod(1ll*phi[n]*work(1,m)%P+work(n,m/n));}inline int Mod_Pow(int x,int a,int mod){    int res=1;    for(int i=0;(1ll<<i)<=a;++i){        if(a&1<<i)res=1ll*res*x%mod;        x=1ll*x*x%mod;    }    return res;}int n,m,p,k;inline int gao(int mod){    if(mod==1)return 0;    int s=gao(phi[mod]);    return Mod_Pow(k,s+phi[mod],mod);}int main(){    for(pret();cin>>n>>m>>p;){        k=work(n,m);        cout<<gao(p)<<endl;    }    return 0;}
3 0
原创粉丝点击