1.题目描述:
2.思路:
- 先求出所有小于等于n的所有质数
- 然后计算每个质数的最大幂,使得该幂小于等于n
- 将所有质数的幂乘起来即为所求
3.理论依据
定理:(A % 987654321) * B % 987654321
的结果,和(A * B) % 987654321
的结果相等。
证明:
if A = m * 987654321 + n
then A * B = (m * B) * 987654321 + n * B
then (A * B) % 987654321 = n * B % 987654321 = (A % 987654321) * B % 987654321
over
推论:由于计算结果很大,所以每次的结果都对987654321取余,不影响最终结果。
4.在解决思路步骤二时,有两个方案:
- 自己写函数,需要格外注意由于数值较大,所以使用
long long
- 使用
#include <cmath>
函数:(long) pow(v.at(i), (long)floor(log(n) / log(v.at(i))))
5.代码如下:
#include <iostream>
#include <vector>
#include <cmath>
using std::vector;
using namespace std;
bool isPrime(long x){ // 判断是否是质数
if (x > 10000) // 根据数据大小进行优化
{
for (long i = 2; i <= x / 100; i++)
{
if (x % i == 0)
return false;
}
}
else if (x > 100)
{
for (long i = 2; i <= x / 10; i++)
{
if (x % i == 0)
return false;
}
}
else{
for (long i = 2; i <= x / 2; i++)
{
if (x % i == 0)
return false;
}
}
return true;
}
long long power(long x, long n){ // 计算质数i的最大幂,使得该幂小于等于n
long long i = x;
long long tmp = i;
while (i <= n)
{
tmp = i;
i *= x; // 100000 * 100000的时候必须用long long保存数值
}
return tmp;
}
int main()
{
int n;
vector<long> v;
while (cin >> n){
// 1.找到质数
for (long i = 2; i <= n; i++)
{
if (isPrime(i))
{
v.push_back(i);
}
}
// 2.求幂 3.连乘
long long result1 = 1;
long long result2 = 1;
for (long i = 0; i < v.size(); i++)
{
// 方案一
result1 = result1 * (long) pow(v.at(i), (long)floor(log(n) / log(v.at(i)))) % 987654321;
// 方案二
result2 = (result2 * power(v.at(i), n)) % 987654321;
}
v.resize(0);
cout << result1 << endl;
cout << result2 << endl;
}
return 0;
}