目录

练习-平方拆分问题线性筛法-筛质数

练习-平方拆分问题(线性筛法-筛质数)

问题描述

小蓝非常热爱数学,一天老师给小蓝出了一道数学题,想锻炼锻炼小蓝的思维能力。题目是这样的:给定两个数 a 和 b,在 a 到 b(包括 a,b)之间所有数的平方当中,试问有几个数能够表示为 x×y 的形式,其中 x 和 y 是质数。你能帮助小蓝一起来解决这个问题吗?

输入格式

第一行两个正整数 a,b,含义同题目所示。

输出格式

输出共一行,输出一个整数,代表那些能够表示为题目描述的形式的平方数的数量。

样例输入

1 5

样例输出

3

说明

样例中,在 1 到 5 之间产生的平方数为:1、4、9、16 和 25。其中只有 4、9 和 25 是满足题目要求的平方数,所以答案为 3。

解题代码:

#include using namespace std; const int N = 1e5 + 10; // 定义常量 N,表示数组的最大大小 int a, b, v[N], pri[N], cnt, ans; // 全局变量定义 // 初始化函数,使用线性筛法预处理所有质数,并标记每个数的最小质因数 void init() { for(int i = 2; i < N; i++) // 从 2 开始遍历每个数 { if(v[i] == 0) // 如果 v[i] == 0,说明 i 是质数 { v[i] = i; // 标记 i 的最小质因数是它本身 pri[++cnt] = i; // 将 i 加入质数数组 pri } for(int j = 1; j <= cnt; j++) // 遍历质数数组 pri { if(pri[j] > v[i] || pri[j] * i >= N) break; // 如果 pri[j] 大于 i 的最小质因数,或者 pri[j] * i 超出范围,则停止 v[pri[j] * i] = pri[j]; // 标记合数 pri[j] * i 的最小质因数是 pri[j] } } } int main() { cin » a » b; // 输入区间 [a, b] init(); // 调用初始化函数,预处理质数 for(int i = a; i <= b; i++) // 遍历区间 [a, b] if(v[i] == i) // 如果 v[i] == i,说明 i 是质数 ans++; // 统计质数个数 cout « ans; // 输出结果 return 0; }

1 问题分析

  • 目标 :统计区间 [a,b]内有多少个数的平方可以表示为两个质数的乘积。
  • 数学性质
  • 如果一个数的平方可以表示为两个质数的乘积,即 n2=p×q,其中 p 和 q 是质数。
  • 由于 n2=p×q,且 p 和 q 是质数,那么 n 必须是两个质数的乘积的平方根。

2 关键观察

1 平方数的性质
  • 平方数 n2 的质因数分解中,每个质因数的指数都是偶数。
  • 如果 n2=p×q,其中 p 和 q 是质数,那么 n 必须是两个质数的乘积的平方根。
2 质数的性质
  • 质数是指只能被 1 和它本身整除的数。
  • 两个质数的乘积 p×q是一个合数,且它的质因数只有 p 和 q。
3 问题的转化
  • 我们需要找到区间 [a,b] 内的数 n,使得 n2 可以表示为两个质数的乘积。
  • 这意味着 n 必须是两个质数的乘积的平方根。

3 解决思路

基于以上观察,我们可以设计以下解决思路:

  1. 预处理质数
  • 使用线性筛法预处理所有质数。
  1. 遍历区间 [a,b]
  • 对于每个数 n,检查 n2 是否可以表示为两个质数的乘积。
  1. 检查 n2 是否可以表示为两个质数的乘积
  • 遍历质数数组 pri,检查是否存在质数 p 使得 p 和 n2/p都是质数。

4 举例说明

假设输入: a = 10, b = 20

执行过程:
  1. 预处理质数
  • 使用线性筛法预处理所有质数。
  • 质数数组 pri = [2, 3, 5, 7, 11, 13, 17, 19, ...]
  1. 统计区间 [10,20] 内的质数
  • 遍历区间 [10,20]:
  • i=10:v[10]=2,不是质数。
  • i=11:v[11]=11,是质数,ans++
  • i=12:v[12]=2,不是质数。
  • i=13:v[13]=13,是质数,ans++
  • i=14:v[14]=2,不是质数。
  • i=15:v[15]=3,不是质数。
  • i=16:v[16]=2,不是质数。
  • i=17:v[17]=17,是质数,ans++
  • i=18:v[18]=2,不是质数。
  • i=19:v[19]=19,是质数,ans++
  • i=20:v[20]=2,不是质数。
  1. 结果
  • 质数有 11,13,17,1911,13,17,19。
  • ans = 4
  • 输出 4。