您的位置:首页 > 编程语言 > C语言/C++

BZOJ 3643 Phi的反函数

2017-06-08 19:28 267 查看

Description



Input

Output

Sample Input

4

Sample Output

5

HINT

Source

By Zky

~~~~~~~~~~~~~~~~~~~~~~~~~~~

欧拉函数+思路+dfs~

ans一定是a1^b1*a2^b2*...*ak^bk,所以n一定是a1^(b1-1)*a2^(b2-1)*...*ak^(bk-1)*(a1-1)*(a2-1)*...*(ak-1)。

这样,我们就可以dfs有哪些质数是a,然后用n除以它们-1后再看是不是ak^(b1-1)相乘的形式。

如果在外面定义了ij,就不要再在for循环里面定义了,这一点要注意啊!

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;

int n,a[10001],c[10001],k;
bool b[100001];
unsigned int ans=(1<<31)+1,kk=ans;

void dfs(int u,int res,long long now,int las)
{
int tot,j;
if(u>1)
{
tot=res;
for(int i=1;i<u;i++) while(!(tot%c[i])) tot/=c[i];
if(tot==1 && res*now<ans) ans=res*now;
}
if(res<a[las+1] || las>a[0]) return;tot=res;
for(int i=1;i<u;i++) while(!(tot%c[i])) tot/=c[i];tot++;
for(j=2;j*j<=tot;j++) if(!(tot%j)) break;
if(j*j>tot && res/(tot-1)*tot*now<ans) ans=res/(tot-1)*tot*now;
for(int i=las+1;(a[i]-1)*(a[i]-1)<=res && i<=a[0];i++)
if(!(res%(a[i]-1)))
{
c[u]=a[i];dfs(u+1,res/(a[i]-1),now*a[i],i);
}
}

int main()
{
scanf("%d",&n);k=sqrt(n);
for(int i=2;i<=k;i++)
{
if(!b[i]) a[++a[0]]=i;
for(int j=1;a[j]*i<=k;j++)
{
b[i*a[j]]=1;
if(!(i%a[j])) break;
}
}
dfs(1,n,1,0);
if(ans==kk) puts("-1");
else cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ dfs 欧拉函数