Problem 500!!! (Project Euler 500)

题目大意:
求出最小的正整数,它的约数有$2^{500500}$个。

 

思路:
考虑将一个数质因数分解,如果它的约数有$2^{500500}$个, 那么每个质因子的指数一定是$2^k-1$这样的形式。

如果把质因子$p$的指数从$2^k-1$增大到$2^{k+1}-1$ 那么相当于在原数的基础上乘以$p^{2^k}$.

所以就可以贪心了, 一开始把足够多的质数放进小根堆里,然后每次取出最小的$x$, 把答案乘上$x$, 然后把$x^2$ 加入堆里。

 

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <set>
 6 #include <cstring>
 7 #include <map>
 8 #include <queue>
 9 using namespace std;
10 
11 typedef long long ll;
12 #define N 10000000
13 #define M 1100
14 typedef pair<int,int> pii;
15 
16 
17 bool flag[N];
18 int p[N],phi[N];
19 
20 
21 void Get_Primes()
22 {
23     phi[1]=1;
24     for (int i=2;i<N;i++)
25     {
26         if (!flag[i]) p[++p[0]]=i,phi[i]=i-1;
27         for (int j=1;j<=p[0] && i*p[j]<N;j++)
28         {
29             flag[i*p[j]]=true;
30             if (i%p[j]==0) 
31             {
32                 phi[i*p[j]]=phi[i]*p[j];
33                 break;
34             }
35             else phi[i*p[j]]=phi[i]*(p[j]-1);
36         }
37     }
38 }
39 
40 
41 priority_queue<ll, vector<ll>, greater<ll> > Q;
42 
43 int main()
44 {
45     freopen("in.in","r",stdin);
46     freopen("out.out","w",stdout);
47     
48     ll ans = 1, mod = 500500507;
49     Get_Primes(); 
50     for (int i = 1; i <= 500500; ++i) Q.push(p[i]);
51     for (int i = 1; i <= 3; ++i)
52     {
53         ll x = Q.top(); 
54         ans =  x % mod;
55         Q.pop(), Q.push(x * x);
56     }
57     cout << ans << endl;
58     return 0;
59 }
View Code

答案:35407281

posted @ 2017-04-26 09:33  lzw4896s  阅读(305)  评论(0编辑  收藏  举报