您的位置:首页 > 其它

BZOJ 3643 Phi的反函数

2017-08-08 15:44 295 查看
3643: Phi的反函数

Time Limit: 10 Sec Memory Limit: 64 MB



Sample Input

4

Sample Output

5

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
#define MAXN 100005
#define LL long long
int n,m,prime[MAXN],tot;
bool is_prime[MAXN];
LL ans;
void Get_Prime(){
memset(is_prime,false,sizeof is_prime );
for(int i=2;i<=50000;i++){
if(!is_prime[i]) prime[++tot]=i;
for(int j=1;j<=tot&&i*prime[j]<=50000;j++){
is_prime[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
return;
}
bool Judge_Prime(int x){
for(int i=2;i<=sqrt(x);i++)
if(x%i==0) return false;
return true;
}
void DFS(int k,int now,LL sum){
if(sum>=ans) return;
if(now==1) { ans=sum;return; }
if(now>m&&Judge_Prime(now+1)) ans=min(ans,sum*(now+1));
for(int i=k+1;prime[i]-1<=m;i++){
if(prime[i]-1 > now) break;
if((now%(prime[i]-1))==0){
int x=now/(prime[i]-1);LL y=sum*prime[i];
DFS(i,x,y);
while(x%prime[i]==0){
x/=prime[i];y*=prime[i];
DFS(i,x,y);
}
}
}
}
int main(){
scanf("%d",&n);m=(int)sqrt(n);
Get_Prime();
ans=(LL)1073741824*2;DFS(1,n,1);
if(ans<=((1<<31)-1)) printf("%lld\n",ans);
else printf("-1\n");
return 0;
}


设 x = p1^a1 * p2^a2 * …* pm^am (m<=10,pi为素数)

则 n == phi(x) == x * (p1-1)p1 (p2-1)p2 …* (pm-1)*pm

== p1^(a1-1) * (p1-1) * p2^(a2-1) * (p2-1) * …* pm^(am-1) * (pm-1)

可以发现:(p1-1)(p2-1) …*(pm-1) 为n的因数

又因为m不会超过10,因此在[2,sqrt(n)]内搜索pi即可,若存在px>sqrt(n),那么这样的x一定只有一个,且ax==1,需要特殊判断

资料来自:http://blog.csdn.net/cjk_cjk/article/details/45858111
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 反函数