Ccodeforces 27E Number With The Given Amount Of Divisors(数论+搜索)

来源:互联网 发布:凯立德找不到导航软件 编辑:程序博客网 时间:2024/05/17 03:53

题意:求因子数恰好为n的最小的正整数,结果不超过1e18。

思路:首先对于一个数分解质因数得到如下形式(p1^a1)*(p2^a2)*(p3^a3)...(pn^an)

那么一个数的因子个数就是(a1+1)*(a2+1)*...*(an+1).

我们尽可能得用较小的素数这样会使答案较小,由于n不超过1000,所以最多也用不到10个素数。

所以可以想到用搜索来做,对于当前素数,分配给它一个指数,注意要判断是否会超过1e18,这里我用的是对数来判断的。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 1100;const int MAXP = 1000; const LL INF = 1e18;int vis[MAXN];int prime[MAXP];void sieve(int n) {int m = (int)sqrt(n+0.5);memset(vis, 0, sizeof(vis));for(int i = 2; i <= m; i++) if(!vis[i]) {for(int j = i*i; j <= n; j+=i) {vis[j] = 1;}}}int gen_prime(int n) {sieve(n);int cnt = 0;for(int i = 2; i <= n; i++) if(!vis[i]){prime[cnt++] = i;}return cnt;}LL pow_mod(LL a, LL b) {if(!b) return 1;LL ans = pow_mod(a, b/2);ans *= ans;if(b&1) ans *= a;return ans;}LL dfs(int n, int num, LL pre) {if(n==1) return 1;LL ans = INF;for(int i = 2; i<=n; i++) {if((double)i-1 > log(1e18/pre)/log(prime[num])) break;if(n%i == 0) {LL tmp = dfs(n/i, num+1, (LL)pow_mod(prime[num], i-1)*pre);if(tmp == INF) continue;ans = min(ans, tmp*(LL)pow_mod(prime[num], i-1));}}return ans;}int main() {    //freopen("input.txt", "r", stdin);int n;cin >> n;int cnt = gen_prime(n);LL ans = dfs(n, 0, 1);cout << ans;    return 0;}


0 0
原创粉丝点击