Phi的反函数
题目描述
求最小的正整数x,使得 φ ( x ) = n \varphi(x)=n φ(x)=n
输入格式
输入正整数 n ( n < 2 31 ) n (n<2^{31}) n(n<231)
输出格式
输出x,如果 x > 2 31 x>2^{31} x>231或者不存在,则输出-1
样例 #1
样例输入 #1
4
样例输出 #1
5
分析
对于一个x,因为质因数唯一分解定理存在:
x
=
p
1
k
1
∗
p
2
k
2
∗
.
.
.
.
.
.
∗
p
m
k
m
=
∏
i
=
1
m
p
i
k
i
x=p_1^{k_1}*p_2^{k_2}* ......*p_m^{k_m}=\prod_{i=1}^mp_i^{k_i}
x=p1k1∗p2k2∗......∗pmkm=i=1∏mpiki
根据
ϕ
(
x
)
的求法,可知:
\phi(x)的求法,可知:
ϕ(x)的求法,可知:
ϕ
(
x
)
=
∑
S
⊆
{
p
1
,
p
2
.
.
.
.
.
,
p
m
}
(
−
1
)
∣
S
∣
n
∏
p
i
∈
S
p
i
\phi(x)=\sum_{S\subseteq\{p_1,p_2.....,p_m\}}(-1)^{|S|}{n\over\prod_{p_i\in S}p_i}
ϕ(x)=S⊆{p1,p2.....,pm}∑(−1)∣S∣∏pi∈Spin
ϕ
(
x
)
=
x
∗
∏
i
=
1
m
(
1
−
1
p
i
)
=
n
\phi(x)=x* \prod_{i=1}^{m} (1-{1 \over p_i})=n
ϕ(x)=x∗i=1∏m(1−pi1)=n
我们发现,n只与p有关,但与k无关,因此对于每个k,均取1时最小,即:
x
m
i
n
=
∏
i
=
1
m
p
i
x_{min}=\prod_{i=1}^mp_i
xmin=i=1∏mpi
ϕ
(
x
m
i
n
)
=
x
∗
∏
i
=
1
m
(
1
−
1
p
i
)
=
x
∗
∏
i
=
1
m
∗
(
p
i
−
1
)
∏
i
=
1
m
p
i
\phi(x_{min})=x* \prod_{i=1}^{m} (1-{1 \over p_i})=x*{{\prod_{i=1}^{m} *(p_i-1)} \over \prod_{i=1}^{m} p_i}
ϕ(xmin)=x∗i=1∏m(1−pi1)=x∗∏i=1mpi∏i=1m∗(pi−1)
进一步化简:
ϕ
(
x
m
i
n
)
=
∏
i
=
1
m
∗
(
p
i
−
1
)
\phi(x_{min})={\prod_{i=1}^{m} *(p_i-1)}
ϕ(xmin)=i=1∏m∗(pi−1)
由此得出规律
代码
#include <bits/stdc++.h>
using namespace std;
const int M=4*1e5+10;
int n;
bool ff=1;
long long ans=3*1e12;
map<int,bool> mp;
bool is_prime(int n){
if (n<=1) return false;
for (int i=2;i<=n/i;i++)
if (n%i==0) return false;
return true;
}
void dfs(int i,int num,int phi){
if (phi>=ans) return;
if(num==1){ans=min(ans,1ll*phi);ff=0;return;}
if (is_prime(num+1)) dfs(i+1,1,phi*(num+1));
for (int ii=2;ii<=num/ii;ii++){
if (num%ii==0 and mp[ii]==0 and is_prime(ii+1)){
mp[ii]=1;
dfs(ii,num/ii,phi*(ii+1));
mp[ii]=0;
}
}
}
signed main() {
cin>>n;
dfs(1,n,1);
if (ff) cout<<-1;
else cout<<ans;
return 0;
}
代码分析
if (is_prime(num+1)) dfs(i+1,1,phi*(num+1));
if (num%ii==0 and mp[ii]==0 and is_prime(ii+1)){
这两行都调用了is_prime函数,但判断的都是某个数+1,这可以方便分解n