正题
题目链接:https://www.luogu.com.cn/problem/P4780
题目大意
给出nnn,求一个最小的xxx满足φ(x)=n\varphi(x)=nφ(x)=n。
若不存在或者大于2312^{31}231则输出−1-1−1。
1≤n≤2311\leq n\leq 2^{31}1≤n≤231
解题思路
考虑用φ\varphiφ比较常用的公式,把nnn拆成若干个∏(pi−1)∗pici\prod (p_i-1)*p_i^{c_i}∏(pi−1)∗pici的形式。因为这个不会超过logloglog个所以可以暴力搜索比较小的质数,然后直到nnn剩下一个pi+1p_i+1pi+1时或111时再暴力判断。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const ll N=46360;
ll n,ans,cnt,pri[N/10];
bool v[N];
void Prime(){for(ll i=2;i<N;i++){if(!v[i])v[i]=1,pri[++cnt]=i;for(ll j=1;j<=cnt&&i*pri[j]<N;j++){v[i*pri[j]]=1;if(i%pri[j]==0)break; }}return;
}
bool IsPri(ll x){if(x%2==0)return 0;for(ll i=3;i*i<=x;i+=2)if(x%i==0)return 0;return 1;
}
void dfs(ll phi,ll x,ll k){if(phi>(1ll<<31))return;if(x==1){ans=min(ans,phi);return;}if(x>sqrt(n)&&IsPri(x+1))ans=min(ans,phi*(x+1));if(pri[k]>x)return;for(ll i=k;i<=cnt;i++){if(x%(pri[i]-1)==0){ll z=x/(pri[i]-1),p=phi*pri[i];dfs(p,z,i+1); while(z%pri[i]==0){p*=pri[i];z/=pri[i];dfs(p,z,i+1);}}}return;
}
signed main()
{scanf("%lld",&n);Prime();ans=(1ll<<32);dfs(1,n,1);if(ans==(1ll<<32))puts("-1");else printf("%lld\n",ans);return 0;
}