BJOI2014 Euler
Description
已知$\varphi (x)=y$,求最小的$x$
Solution
$$\left\{
\begin{aligned}
\varphi(x)=x\prod_{i=1}^n \frac{p_i-1}{p_i} \\
x=p_1^{q_1}p_2^{q_2}\cdots p_n^{q_n}
\end{aligned}
\right.$$
化简得
$$y=p_1^{q_1-1}p_2^{q_2-1}\cdots p_n^{q_n-1}\prod_{i=1}^n {p_i-1}$$
枚举$y$中所有因数,找到所有的$p$,DFS组合所有$x$
#pragma GCC optimize(2) #include<algorithm> #include<iostream> #include<cstdio> using namespace std; long long T,y,ans,tot,p[1000000]; inline long long read() { long long f=1,w=0; char ch=0; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { w=(w<<1)+(w<<3)+ch-'0'; ch=getchar(); } return f*w; } bool check(long long x) { for(long long i=2;i*i<=x;i++) if(!(x%i)) return false; return true; } bool split(long long cnt,long long now) { while(!(now%p[cnt])) now/=p[cnt]; return now==1; } void dfs(long long cnt,long long now,long long ret) { if(cnt>tot||ret>ans) return; dfs(cnt+1,now,ret); if(!(now%(p[cnt]-1))) { if(split(cnt,now/(p[cnt]-1))) ans=min(ans,ret/(p[cnt]-1)*p[cnt]); now/=(p[cnt]-1); dfs(cnt+1,now,ret/(p[cnt]-1)*p[cnt]); while(!(now%p[cnt])) { now/=p[cnt]; dfs(cnt+1,now,ret/(p[cnt]-1)*p[cnt]); } } } bool cmp(long long a,long long b) { return a>b; } int main() { T=read(); for(;T;T--) { tot=0; y=read(); if(y==1) { puts("1"); continue; } ans=1ll<<60; for(long long i=1;i*i<=y;i++) if(!(y%i)) { if(check(i+1ll)) p[++tot]=i+1ll; if(i*i==y) continue; if(check(y/i+1ll)) p[++tot]=y/i+1ll; } sort(p+1,p+tot+1,cmp); dfs(1,y,y); printf("%lld\n",ans); } return 0; }