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 }
答案:35407281
Every day is meaningful, keeping learning!