【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);
}

 

posted @ 2017-09-17 21:29  TS_Hugh  阅读(247)  评论(0编辑  收藏  举报