目录
4658. 质因数个数
题目描述
运行代码
#include<iostream>
using namespace std;
typedef long long ll;
ll n;
int count(ll x) {
int c = 0;
for(ll i=2;i<=x/i;i++)
if (x % i == 0) {
while (x % i == 0)x /= i;
c++;
}
if (x > 1)c++;
return c;
}
int main() {
cin >> n;
cout << count(n);
return 0;
}
代码思路
-
定义了一个函数
count
,用于计算给定整数x
的不同质因数的个数。- 初始化一个计数器
c
为 0 。 - 从 2 到
x
的平方根进行遍历。如果x
能被当前的i
整除,就通过一个内层循环不断用x
除以i
,去除该质因数的影响,并将计数器c
加 1 。 - 检查如果经过上述循环后
x
仍然大于 1,说明x
本身是一个未被除尽的质因数,将计数器c
加 1 。 - 最后返回计数器
c
,即质因数的个数。
- 初始化一个计数器
-
在
main
函数中:- 读入一个整数
n
。 - 调用
count
函数计算n
的不同质因数的个数,并将结果输出。
- 读入一个整数
197. 阶乘分解
题目描述
运行代码
#include <iostream>
using namespace std;
const int N = 1000006;
int primes[N], cnt;
bool st[N];
void Primes(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = i;
for (int j = i; j <= n; j += i) {
st[j] = true;
}
}
}
}
int main() {
int n;
cin >> n;
Primes(n);
int c[N] = {0};
for (int i = 0; i < cnt; i++) {
int p = primes[i];
int num = 0;
for (int j = p; j <= n; j += p) {
int x = j;
while (x % p == 0) {
num++;
x /= p;
}
}
c[i] = num;
}
for (int i = 0; i < cnt; i++) {
if (c[i]) cout << primes[i] << " " << c[i] << endl;
}
return 0;
}
代码思路
-
Primes
函数:- 从 2 到
n
遍历每个数i
。 - 如果
st[i]
为false
,说明i
是一个未被标记的数,即可能是质数。 - 将
i
存入primes
数组,并增加cnt
计数。 - 然后通过一个循环,将
i
的倍数(从i
本身开始,每次增加i
)都标记为合数(st[j] = true
)。
- 从 2 到
-
在
main
函数中:- 读入一个整数
n
,调用Primes(n)
函数来获取小于等于n
的所有质数并存入primes
数组。 - 初始化一个数组
c[N]
,用于记录每个质数在n!
中的出现次数。 - 对于每个质数
primes[i]
,通过一个内层循环从该质数开始,每次增加该质数,检查每个能被该质数整除的数,计算其能被整除的次数,并将总次数累加到num
中,最后将num
存入c[i]
。 - 最后遍历
c
数组,输出每个出现次数不为 0 的质数及其在n!
中的出现次数。
- 读入一个整数
其他代码
#include <iostream>
using namespace std;
const int N = 1000006;
int primeNums[N], primeCnt = 0;
bool isComp[N * 2];
// 筛选质数的函数
void findPrimes(int n) {
for (int i = 2; i <= n; i++) {
if (isComp[i]) continue;
for (int j = 2; j * i <= n; j++) {
isComp[i * j] = true;
}
}
for (int i = 2; i <= n; i++) {
if (!isComp[i]) primeNums[++primeCnt] = i;
}
}
int main() {
int num;
cin >> num;
findPrimes(num);
for (int i = 1; i <= primeCnt; i++) {
int temp = num, curPrime = primeNums[i], cnt = 0;
while (temp) {
cnt += (temp / curPrime);
temp /= curPrime;
}
cout << curPrime << " " << cnt << endl;
}
return 0;
}
代码思路
-
findPrimes
函数:- 这个函数的目的是筛选出小于等于
n
的所有质数。 - 首先外层循环从 2 到
n
遍历每个数i
。 - 如果
isComp[i]
为true
,说明i
已经被标记为合数,直接跳过。 - 对于未标记为合数的
i
,通过内层循环将i
的倍数(从 2 倍开始到小于等于n
)标记为合数(设置isComp[i * j] = true
)。 - 再次遍历从 2 到
n
,将未被标记为合数的数存入primeNums
数组,并通过primeCnt
记录质数的个数。
- 这个函数的目的是筛选出小于等于
-
main
函数:- 读入一个整数
num
。 - 调用
findPrimes(num)
函数获取小于等于num
的所有质数。 - 然后通过一个循环,对于每个找到的质数
primeNums[i]
(从 1 开始到primeCnt
):- 初始化
temp
为num
,cnt
为 0 。 - 通过一个内层循环,不断计算
temp
中有多少个primeNums[i]
,每有一个就将cnt
加 1 ,并更新temp
为temp / primeNums[i]
。 - 最后输出当前的质数
primeNums[i]
和它在num
中的出现次数cnt
。
- 初始化
- 读入一个整数
模板题【线性筛求积性函数】
题目描述
A-模板题【线性筛求积性函数】_牛客竞赛数学专题班积性函数(积性函数概念、欧拉筛求积性函数、莫比乌斯反演) (nowcoder.com)
运行代码
#include<iostream>
using namespace std;
typedef long long ll;
int q,n;
int main(){
cin>>q;
while(q--){
cin>>n;
ll ans=1;
for(int i=2;i*i<=n;i++){
int cnt=0;
while(n%i==0){
n/=i;
cnt++;
}
ans*=(cnt+1);
}
if(n>1)
ans*=2;
cout<<ans<<endl;
}
}
代码思路
- 首先,通过
cin >> q
读取测试用例的数量q
。 - 然后,进入一个
while
循环,每次处理一个测试用例。- 读取当前测试用例中的整数
n
。 - 初始化结果变量
ans
为 1 。 - 通过一个
for
循环从 2 开始,直到i * i <= n
,尝试找出能整除n
的数i
。 - 对于每个能整除
n
的数i
,使用一个内部的while
循环计算n
中包含i
的个数cnt
,同时不断更新n
为n / i
。 - 将
ans
乘以(cnt + 1)
,这是因为一个数的某个质因数i
的指数为cnt
时,该质因数对因数个数的贡献为cnt + 1
。 - 当循环结束后,如果
n
仍然大于 1 ,说明n
本身是一个质数,将ans
乘以 2 。 - 最后输出
ans
,即n
的因数个数。
- 读取当前测试用例中的整数