https://projecteuler.net/problem=182
题意:
找出满足下列条件的所有$e$ 的和,
- $1 < e < varphi left( {1009,3643}
ight)$
- $gcd(e,φ)=1$
- 满足${m^e} equiv m{
m{ }}mod {
m{ }}n$ 的$m$的个数最小
解答:
这道题最重要的就是解决这个问题:
${m^e} equiv m{ m{ }}mod { m{ }}n$ 中$e$确定时,$m$的取值的个数。
由于n是合数,且 $n = p*q$ ,所以先考虑${m^e} equiv m{ m{ }}mod { m{ }}p$ 和 ${m^e} equiv m{ m{ }}mod { m{ }}q$ ,
$m({m^{e - 1}} - 1) equiv 0{ m{ }}mod { m{ }}p$ , $p$ 是质数
- $m==0$ ,恒成立
- $m!=0$ ,${m^{e - 1}} equiv 1mod {
m{ }}p$
考虑 ${a^b} equiv 1mod p$ ,$a$ 、$p$ 互素,此式中$b$确定时,$a$的个数
因为$p$ 为素数,所以必存在原根$r$ ,使得$ a= {r^k}$ ,
${r^{kb}} = 1{ m{ }}mod { m{ }}p$
这里很容易联想到关于${a^k}mod { m{ }}p$的阶那个公式,
$ord({r^b}) = frac{{varphi (p)}}{{(varphi (p),b)}},(r,p) = = 1$
变换一下位置,
$(varphi (p),b) = frac{{varphi (p)}}{{ord({r^b})}},(r,p) = = 1$
${r^{ord({r^b})}}$ ,${r^{2ord({r^b})}}$ ,...,${r^{(varphi (p ),b )ord({r^b})}}$就是使上式成立的$a$的可能取值,
所以左边就是解的个数。
所以最初的解为$gcd (varphi (p),b) = gcd (p - 1,b)$
回到上面,还有$m==0$ 的情况,
所以解为$gcd (varphi (p),b)+1 = gcd (p - 1,b)+1$
再看如何解决模数不为质数的问题,这里 就需要用到中国剩余定理,根据中国剩余定理,每一对$p$ 和 $q$ ,就会产生一个解,依据乘法原理,所以最后的解为$[gcd (p - 1,e - 1) + 1]*[gcd (q - 1,e - 1) + 1]$
接下来:就是枚举$e$ 的问题了
- 直接进行暴力
- 观察$e$,因为$gcd ((p - 1)(q - 1),e ) = = 1$ ,故$e$ 为奇数,$e-1$ 为偶数, $gcd (e - 1,p - 1) > = 2$ ,
$gcd (e - 1,q - 1) > = 2$ ,这里确定了两个gcd的下界的最小值,而且显然这两个下界在枚举$e$ 的过程中是可以取到的,所以这里可以直接判断最小的情况。
复杂度:$O(nlog n)$ ,其中$logn$ 是辗转相除的复杂度,证明见维基百科。
代码1:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll inf=1<<30; 5 ll p=1009,q=3643,factor[4070000]; 6 ll n=q*p,phi=(p-1)*(q-1),mi=inf,ans; 7 int main(){ 8 for(ll i=2;i<phi;++i) if(__gcd(i,phi)==1) factor[i]=(__gcd(i-1,p-1)+1)*(__gcd(i-1,q-1)+1),mi=min(mi,factor[i]); 9 for(ll i=2;i<phi;++i) if(factor[i]==mi) ans+=i; 10 printf("%lld ",ans); 11 }
代码2:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll inf=1<<30; 5 ll p=1009,q=3643; 6 ll n=q*p,phi=(p-1)*(q-1),ans; 7 int main(){ 8 for(ll i=3;i<phi;++i) if(__gcd(i,phi)==1&&__gcd(i-1,q-1)==2&&__gcd(i-1,p-1)==2) ans+=i; 9 printf("%lld ",ans); 10 }