您的位置:首页 > 其它

bzoj3643 Phi的反函数

2017-05-30 17:16 381 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3643

【题解】

n = p1^a1*p2^a2*...*pm^am

phi(n) = p1(p1-1)^(a1-1)*p2(p2-1)^(a2-1)*...*pm^(am-1)

最多有10个不同的质因数就超过maxint了,这告诉我们可以搜索

我们假设p1<p2<p3<...<pm

那么我们处理出<sqrt(n)的质数,因为我们只会用到这些质数来搜(因为其他平方完就爆炸了)

那么我们就暴力尝试是否被(pi-1)整除,是的话枚举因子个数,dfs下去即可

注意特判如果我当前剩下了n,n+1是个质数,那么也可以是直接当前答案*(n+1)

复杂度……我咋知道

O(能过)

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e4 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

ll ans = 1e18;
int n, F;
bool isnp[M];
int p[M/3], pn=0;

inline bool isprime(int n) {
for (int i=1, to = sqrt(n); p[i] <= to; ++i)
if(n % p[i] == 0) return false;
return true;
}

inline void dfs(int n, int lst, ll sum) {
if(sum >= ans) return;
if(n == 1) { ans = sum; return ; }
if(n > F && isprime(n+1)) ans = min(ans, sum*(n+1));
for (int i=lst+1; p[i]-1 <= F && p[i]-1 <= n; ++i) {
if(n % (p[i]-1) == 0) {
int t = n/(p[i]-1); ll res = sum * p[i];
dfs(t, i, res);
while(t % p[i] == 0) {
t /= p[i];
res *= p[i];
dfs(t, i, res);
}
}
}
}

int main() {
cin >> n;
F = sqrt(n);
isnp[0] = isnp[1] = 1;
for (int i=2; i<=50000; ++i) {
if(!isnp[i]) p[++pn] = i;
for (int j=1; j<=pn && i*p[j] <= 50000; ++j) {
isnp[i*p[j]] = 1;
if(i%p[j] == 0) break;
}
}
dfs(n, 0, 1);
if(ans <= 2147483647) cout << ans << endl;
else cout << -1 << endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: