【BZOJ 3643】Phi的反函数 数搜索
这道题是典型的数搜索,讲究把数一层一层化小,而且还有最重要的大质数剪枝。
#include <cstdio> #include <cmath> typedef long long LL; int n; const int N=100010; const LL Inf=0x7fffffff; LL ans; int len,prime[N]; bool isnot[N]; inline void getprime(){ int lim=100000; for(int i=2;i<=lim;i++){ if(!isnot[i])prime[++len]=i; for(int j=1;prime[j]*i<=lim;j++){ isnot[prime[j]*i]=1; if(i%prime[j]==0)break; } } } inline bool isprime(int x){ if(x==1)return 0; int lim=(int)sqrt(x+0.5); for(int i=1;prime[i]<=lim;i++) if(x%prime[i]==0) return 0; return 1; } inline LL Min(LL x,LL y){ return x<y?x:y; } void dfs(int pos,LL now,int rest){ if(pos>=len)return; if(now>=ans)return; if(rest==1){ans=now;return;} if(isprime(rest+1)){ans=Min(ans,now*(rest+1));return;} LL have=prime[pos]-1,j=prime[pos]; if(pos==1)have<<=1,j<<=1; while(rest%have==0) dfs(pos+1,now*j,rest/have),have*=prime[pos],j*=prime[pos]; dfs(pos+1,now,rest); } int main(){ getprime(),scanf("%d",&n),ans=Inf+1; if(n<=0){printf("-1");return 0;} if(n==1){printf("1");return 0;} dfs(1,1,n); printf("%lld",ans==Inf+1?-1:ans); }
苟利国家生死以, 岂因祸福避趋之。