F. 1.小W 的质数(prime)[欧拉筛再理解]
Description
小X是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感。小X认为,质数是一切自然数起源的地方。
在小X的认知里,质数是除了本身和1以外,没有其他因数的数字。但由于小X对质数的热爱超乎寻常,所以小X同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
于是,我们定义,一个数是小X喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。 而现在,小X想要知道,在L到R之间,有多少数是他喜欢的数呢?
Input
第一行输入一个正整数Q,表示询问的组数。 接下来Q行,包含两个正整数L和R,保证L≤R
Output
输出Q行,每行一个整数,表示小X喜欢的数的个数。
理解不到位啊..最开始没想着直接筛,使用了质因数快速分解配合miller_Rabin去做,O(n^(5/4))的复杂度卡的死死的。
其实还是欧拉筛理解不到位。顺便检查了自己的板子和其他人的不同。
LL v[maxn],primes[maxn];//v[i]存的是i的最小质因子,primes[m]里面存筛出来的质数void getprimes(int n)
{memset(v,0,sizeof(v));//最小质因子 LL m=0;//质数数量 for(LL i=2;i<=n;i++){if(v[i]==0) {v[i]=i;primes[++m]=i;}//i是质数 //给当前的数i乘上一个质因子for(LL j=1;j<=m;j++){//i有比primes[j]更小的质因子,或者超出n的范围,停止循环 if(primes[j]>v[i]||primes[j]>n/i) break;//primes[j]是合数i*primes[j]的最小质因子 v[i*primes[j]]=primes[j];} }for(LL i=1;i<=m;i++) cout<<primes[i]<<endl;
}
bool vis[N]; //vis[i] = 1,表示非素数//vis[i] = 0,表示素数
int prime[N], cnt;
//prime数组用来放素数,cnt用来记录数组用了多少void getPrime(const int n) {vis[1] = 1; //1不是素数for (int i = 1; i <= n; i++) {if (!vis[i]) {prime[++cnt] = i; //记录素数}for (int j = 1; j <= cnt && i <= n / prime[j]; j++) {vis[i * prime[j]] = 1; //标记合数if (i % prime[j] == 0) {break;}}}
}
重新理解:
欧拉筛的原理是保证在 2~n 范围中的每一个合数都能被唯一分解成它的最小质因数与除自己外最大的因数相乘的形式。
因此我们枚举2~n中的每一个数作为筛法中的“除自己外的最大因数”,如果它未被标记为合数,就先将它放入素数表内,再将这个最大因数与素数表中已经找到的素数作为最小质因数相乘,将得到的这些数标记为合数。最后输出得到的素数表即可。
对于 i%prime[j] == 0 就break的解释 :
当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。
举个例子 :i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。因为欧拉筛法的原理便是通过最小素因子来消除
对于这个题来说:需要边筛边标记每次的质数*质数。
如果是上份板子:
void getprimes(LL n){for(LL i=2;i<=n;i++){if(v[i]==0) {v[i]=i;primes[++m]=i;is[i]=true;}for(LL j=1;j<=m;j++){if(primes[j]*i>n||primes[j]>v[i]) break;v[primes[j]*i]=primes[j];is[primes[j]*v[i]]=true;///题目要求筛出两个质数乘积的合数}}
}
下份:
void getprimes(LL n){for(LL i=2;i<=n;i++){if(v[i]==0) {primes[++m]=i;is[i]=true;}for(LL j=1;j<=m;j++){if(primes[j]*i>n) break;v[primes[j]*i]=primes[j];if(!v[i]) is[primes[j]*i]=true;if(i%primes[j]==0) break;}}
}
F. 1.小W 的质数(prime)[欧拉筛再理解]相关推荐
- AcWing 868. 筛质数(欧拉筛模板)
题目连接 https://www.acwing.com/problem/content/870/ 思路 欧拉筛模板,学习链接:https://acmer.blog.csdn.net/article/d ...
- 【C++】快速判断质数(6的倍数法)、快速获取n以下的质数(欧拉筛)板子
快速判断质数(6的倍数法)板子 bool judge(int num) {if (num == 2 || num == 3) {return true;}//如果num不在6的倍数附近,则不是素数if ...
- 2404 Super Prime(欧拉筛素数)
2404 Super Prime(欧拉筛素数) Problem Description We all know, prime is a kind of special number which has ...
- 【筛质数】——朴素筛,埃式筛,欧拉筛
题目描述: 题目分析: 这道题可以用,朴素筛,埃氏筛,欧拉筛来写. 普通筛: 时间复杂度:O(n logn) 时间复杂度太高,会超时的!!(9/10) #include <iostream> ...
- 筛选质数,埃氏筛和欧拉筛(线性筛)
求len之内的所有的素数 除了比较常用的开根号的求法,还有两种更好的方法,埃氏筛和线性筛.其中埃氏筛更好理解,而线性筛(欧拉筛)不好理解但是更快. 埃氏筛 #include <bits/stdc ...
- 数据结构与算法:欧拉筛——查找素数(质数)的最优解算法 O(n)
前言:众所周知,查找素数是算法题中最基础的问题,也是经常被问到的问题. 但往往同学们找不到最优解法,因而导致 时间复杂度 过大而超出限制. 下面列出常用的求 ...
- poj3518(Prime Grap 欧拉筛+二分)
用欧拉筛打表,二分搜索,过.... #include <iostream> #include <algorithm> #include <string.h> #in ...
- 埃氏筛 线性筛(欧拉筛) 算法解析
埃氏晒 埃拉托斯特尼筛法,简称埃氏晒,是一种用来求自然数n以内的全部素数. 他的基本原理是,如果我们要获得小于n的所有素数,那就把不大于根号n的所有素数的倍数剔除. 埃氏晒的原理很容易理解,一个合数, ...
- 素数的线性筛法java,埃氏筛 线性筛(欧拉筛) 算法解析
埃氏晒 埃拉托斯特尼筛法,简称埃氏晒,是一种用来求自然数n以内的全部素数. 他的基本原理是,如果我们要获得小于n的所有素数,那就把不大于根号n的所有素数的倍数剔除. 埃氏晒的原理很容易理解,一个合数, ...
最新文章
- [实现] 利用 Seq2Seq 预测句子后续字词 (Pytorch)2
- IntelliJ IDEA 的Project structure说明
- Java-ORM数据库框架CDM介绍
- 『ORACLE』 配置共享服务器(11g)
- NET 应用架构指导 V2 学习笔记(十九) 表现层组件设计指导
- source insight 4.0的基本使用方法
- java security 详解_Spring Security入门教程 通俗易懂 超详细 【内含案例】
- 使用Cloud Application Programming模型开发OData的一个实际例子
- Solution 19: Fibonacci数列
- 斯坦福大学机器学习公开课视频及课件
- phpStudy下载安装+配置站点+You don't have permission to access / on this server错误解决
- jetson nano 相关设置(开机自动登录、取消休眠和屏保、开机自启动程序)
- 学以致用一 安装centos7.2虚拟机
- 【Leetcode】Remove Duplicates from Sorted Array II
- 斐讯k2路由器刷PandoraBox一宽带多人用
- macbook 终端命令怎么使用_mac怎么打开终端?mac打开命令提示符的方法
- pull request 时遇到 conflicted 的解决方法
- 卿学姐与诡异村庄(并查集)
- 【Python】大数相乘
- win11 安装make (gnu make)