您的位置:首页 > 其它

hdu 5728 PowMod 数论

2016-10-05 19:33 375 查看

PowMod

先贴官方题解



其中第二段根本不懂。。。然后就去学习了一下

引理:设 p 为 n 的一个质因数,

if p2|n then φ(n)=φ(np)∗p else φ(n)=φ(np)∗φ(p)

前一部分可以用 φ(n) 的定义来证明,后一部分就是积性函数的性质(详见欧拉函数为什么是积性函数)

题中”n is a square-free number”表示 n 没有平方因子。

我们设 p 为 n 的一个质因数,对 p∣i 的情况分类讨论:

∑i=1mφ(i∗n)=∑p∤imφ(i∗n)+∑p∣imφ(i∗n)=φ(p)∗∑p∤imφ(i∗np)+p∗∑p∣imφ(i∗np)(∵ p is a prime number)=φ(p)∗∑p∤imφ(i∗np)+(φ(p)+1)∗∑p∣imφ(ip∗n)(∵{i,p∣i}∪{i,p∤i}={i})=φ(p)∗∑i=1mφ(i∗np)+∑p∣imφ(ip∗n)=φ(p)∗∑i=1mφ(i∗np)+∑i=1m/pφ(i∗n)

再解释另一个式子:ab≡aφ(p)+b%φ(p)(modp),我们分两种情况:

a与p互质,那么由费马-欧拉定理,aφ(p)≡1(modp),原式成立;

a与p不互质,则ax在φ(p)次之内就会变为0。需要一个条件,b≥φ(p),那么实际上ab≡aφ(p)+b%φ(p)≡0(modp),原式成立。

但是为什么满足b≥φ(p)我还是觉得很难解释,代码是抄标程的:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;
typedef pair<int,int> PII;
const int MOD=1000000007;
const int N=1e7+5;
bool b
;
int phi
,s
,prime[700000];
int tot=0;

void getphi()
{
phi[1]=1;
for (int i=2;i<N;i++) {
if (!b[i]) {
phi[i]=i-1;
prime[++tot]=i;
}
for (int j=1;j<=tot;j++) {
if (i*prime[j]>=N) break;
b[i*prime[j]]=1;
if (i%prime[j]==0) {
phi[i*prime[j]]=phi[i]*prime[j];
} else {
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
s[0]=0;
for (int i=1;i<N;i++)
s[i]=(s[i-1]+phi[i])%MOD;
}

int getsum(int n,int m)
{
if (m==0) return 0;
if (m==1) return phi
;
if (n==1) return s[m];
for (int i=1;i<=tot;i++) {
if (n%prime[i]==0)
return (1LL*(prime[i]-1)*getsum(n/prime[i],m)%MOD+getsum(n,m/prime[i]))%MOD;
}
return 0;
}

int pow(long long x,int n,int M)
{
long long res=1;
while (n) {
if (n&1) res=res*x%M;
x=x*x%M;
n>>=1;
}
return res;
}

int solve(int k,int p)
{
if (p==1) return 0;
int now=solve(k,phi[p]);
return pow(k,phi[p]+now,p);
}

int main()
{
int n,m,p;
getphi();
//  printf("%d\n",tot);
while (scanf("%d%d%d",&n,&m,&p)!=EOF) {
int k=getsum(n,m);
printf("%d\n",solve(k,p));
}
return 0;
}


本篇博客借助 markdown 高清重制~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息