打素数表
这个其实实用就好,不需要特别快。
给出我三个经常用的线性素数筛模板
一、普通筛
原理很简单,找到一个素数,然后把它所有的倍速都标记一下就行,由于会重复标记,所以时间复杂度比较高
//普通筛 void get_table() { cnt = 0; vis[0] = 1; vis[1] = 1; for(int i = 2; i <= MX; ++i) { if(!vis[i]) prime[cnt++] = i; for(int j = i*i; j <= MX; j += i) vis[j] = 1; } }
二、线性筛
线性筛其实原理就是优化了朴素素数筛法, 也就是比一个合数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到
int get_table() { cnt = 0; vis[0] = 1; vis[1] = 1; for(int i = 2; i <= MX; ++i) { if(!vis[i]) prime[cnt++] = i; for(int j = 0; j<cnt&&i*prime[j]<MX; ++j) { vis[i*prime[j]] = 1; if(i%prime[j]==0) break; ///即比一个合数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到 ///也就是防止重复筛 } } }
简单版本:
void get_table() { cnt = 0; vis[0] = 1 ; vis[1] = 1; for(int i = 2; i <= MX; ++i) { if(!vis[i]) prime[cnt++] = i; for(int j = 0; j<cnt&&i*prime[j]<MX; ++j) { vis[i*prime[j]] = 1; } } }
化繁为简 大巧不工

浙公网安备 33010602011771号