AT2286 题解
作者:互联网
小学生又双叒叕来写题解啦!
这题要用到因数个数定理,没学过的童鞋自己了解一下。
由于和质数有关,我使用质数筛法。
我使用较快的欧拉筛法算质数(想学就做这题)。
事实上,由于范围不大,使用普通的埃氏筛也行。
最后一个问题是:枚举质因数个数。
相信这不难,只需暴力分解质因数即可。
把上文提到的三个模块结合起来即可。
送上AC代码
#include <iostream>
#include <cstdio>
#define MOD (int)(1e9 + 7)
using namespace std;
int p[1005], cur;
bool flag[1005]; //true 是合数,false 是质数。
void ES(int n)
//欧拉筛。
{
flag[0] = true, flag[1] = true; //特判。
for (long long i = 2; i <= n; i++) //枚举范围。
{
if (flag[i] == false) //i 是质数。
{
cur++;
p[cur] = i; //存入质数数组。
}
//扫一遍 p 数组。此处 i 的作用为:倍数。
for (int j = 1; j <= cur; j++)
{
//很好理解。超出范围,用不着枚举。
if (i * p[j] > n) break;
//若没有跳出,记录合数(筛掉)。
flag[i * p[j]] = true;
//较难理解。简单地说,p[j] 的"过关门槛"比 i低,所以在这之前,已经筛过了。
if (i % p[j] == 0) break;
}
}
}
int fac[1005]; //因数个数。
void calc(int n) //作用为:分解 n的质因数。
{
for (int i = 1; i <= cur && n != 1; i++)
while (n % p[i] == 0)
{
fac[i]++;
n /= p[i];
}
}
int main()
{
int n;
scanf("%d", &n);
ES(n);
for (int i = 1; i <= n; i++) //枚举n中的每一个数。
{
int t = i;
calc(t); //分解 t。
}
long long mul = 1;
//别忘开 long long,为什么开不解释。
for (int i = 1; i <= cur; i++) mul = (mul * (fac[i] + 1)) % MOD; //因数个数定理。
printf("%lld\n", mul); //AT题祖传换行。
return 0;
}
超时是不可能的,跑得飞快!
首发:2022-01-27 19:50:29
标签:AT2286,int,题解,质数,flag,1005,质因数,true 来源: https://www.cnblogs.com/liangbowen/p/16622743.html