思考:关于数据范围,由于范围是[1e9],那么质数只需要最多筛选前20个就可以了
分析:首先,欧拉函数 f(n)=1~n中所有与n互质的元素的个数
f(n)=n(1-1/p1)(1-1/p2)...(1-1/pk)
f(n)/n=(1-1/p1)(1-1/p2)...(1-1/pk)
那么,通过找规律我们发现
运用欧拉函数的模板可以得出
1: 1/1
2: 1/2
3: 2/3
4: 1/2
5: 4/5
6: 1/3
7: 6/7
8: 1/2
9: 2/3
10: 2/5
11: 10/11
12: 1/3
13: 12/13
14: 3/7
...
可以发现一个性质:
- [2,n] 函数值最小的数=尽可能多个质数的乘积
- [2,n] 函数值最大的数=最大的质数
对于第一个问题最小的数,就去枚举前n个质数的乘积
对于第二个问题最大的数,从n往下开始找到最大的质数
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 25;
int p[N] = { 2,3,5,7,11,13,17,19,23,29,31,37 };
typedef long long ll;
bool is_prime(int n)
{
for (int i = 2;i <= n / i;i++)
if (n % i == 0) return false;
return true;
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
if(n==1) {
cout<<-1<<endl;continue;
}
ll minn = 1, maxx = 1;
int i = 0;
//需要开ll,不然会爆int
while (minn * p[i] <= n)
minn =minn* p[i],i++;
for (maxx = n;maxx >= 2;maxx--)
if (is_prime(maxx))
break;
cout << minn << ' ' << maxx << "\n";
}
return 0;
}