4658. 质因数个数、197. 阶乘分解、模板题【线性筛求积性函数】(数论练习题)

21 篇文章 0 订阅

目录

4658. 质因数个数

题目描述

运行代码

代码思路

197. 阶乘分解

题目描述

运行代码

代码思路

其他代码

代码思路

模板题【线性筛求积性函数】

题目描述

​编辑

运行代码

代码思路

4658. 质因数个数

题目描述

4658. 质因数个数 - AcWing题库

运行代码

#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;
}

代码思路

  1. 定义了一个函数 count ,用于计算给定整数 x 的不同质因数的个数。

    • 初始化一个计数器 c 为 0 。
    • 从 2 到 x 的平方根进行遍历。如果 x 能被当前的 i 整除,就通过一个内层循环不断用 x 除以 i ,去除该质因数的影响,并将计数器 c 加 1 。
    • 检查如果经过上述循环后 x 仍然大于 1,说明 x 本身是一个未被除尽的质因数,将计数器 c 加 1 。
    • 最后返回计数器 c ,即质因数的个数。
  2. 在 main 函数中:

    • 读入一个整数 n 。
    • 调用 count 函数计算 n 的不同质因数的个数,并将结果输出。

197. 阶乘分解

题目描述

197. 阶乘分解 - AcWing题库

运行代码

#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;
}

代码思路

  1. 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;
}

代码思路

  1. findPrimes 函数:

    • 这个函数的目的是筛选出小于等于 n 的所有质数。
    • 首先外层循环从 2 到 n 遍历每个数 i 。
    • 如果 isComp[i] 为 true ,说明 i 已经被标记为合数,直接跳过。
    • 对于未标记为合数的 i ,通过内层循环将 i 的倍数(从 2 倍开始到小于等于 n )标记为合数(设置 isComp[i * j] = true )。
    • 再次遍历从 2 到 n ,将未被标记为合数的数存入 primeNums 数组,并通过 primeCnt 记录质数的个数。
  2. 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;
    }
}

代码思路

  1. 首先,通过 cin >> q 读取测试用例的数量 q 。
  2. 然后,进入一个 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 的因数个数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值