线性筛法
what is 线性筛??就是基于最基本的筛法的优化。
在基础的筛法上,我们发现有的数字会被重复筛,例如6既会被2枚举到也会被3枚举到,必然有重复运算。
我们的做法就是让每一个数的最小因数筛。
F O R \mathrm{FOR} FOR E X A M P L E : \mathrm{EXAMPLE}: EXAMPLE:
有一个数 2 ∗ 2 ∗ 3 ∗ 5 2 * 2 * 3 * 5 2∗2∗3∗5
有另一个数 3 ∗ 3 ∗ 3 ∗ 5 3 * 3 * 3* 5 3∗3∗3∗5
那么第一个数枚举到3的话,筛到的数字是 2 ∗ 2 ∗ 3 ∗ 3 ∗ 5 2 * 2 * 3 * 3 * 5 2∗2∗3∗3∗5
但是在第二个数字再次枚举的时候 枚举到2时 也会枚举到 2 ∗ 2 ∗ 3 ∗ 3 ∗ 5 2 * 2 * 3 * 3 * 5 2∗2∗3∗3∗5
因此,维护这个最小指引数即可。
怎么维护??
当 i i i m o d mod mod 这 个 质 因 数 这个质因数 这个质因数 = 0 =0 =0 说明是质因数,第一次枚举到就要 b r e a k break break,这样就保证了一定会被最小素因数给筛。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,cnt=0;
int prime[10000]={
};//用来存储素数
int Vis[10000]={
};//用来判断是否是素数
cin>>n;
for (int i=2;i<=n;i++)
{
if (Vis[i]==0) prime[++cnt]=i;//如果没有被标记过
for (int j=1;j<=cnt&&i*prime[j]<=n;j++)//用i去乘上每一个已经求过的素数
{
Vis[i*prime[j]]=1;//标记素数
if (i%prime[j]==0) break;//下面再解释
}
}
for (int i=2;i<=n;i++)
if (Vis[i]==0) cout<<i<<' ';
return 0;
}
一、欧拉函数概念
欧拉函数,是表示1~n中与n互质的元素的个数,记为 φ ( n ) φ(n) φ(n)。
二、性质
- 如果n为某一素数p,显然 φ ( p ) φ(p) φ(p)为p-1
- 如果n为某一素数的幂次,那么: ϕ ( p a ) = ( p − 1 ) ∗ p a − 1 \phi(p^a)=(p-1)*p^ {a-1} ϕ(pa)=(p−1)∗pa−1
我们可以来推导次函数的求法
我们先将n分解质因数得:
n = a 1 b 1 ∗ a 2 b 2 ∗ a 3 b 3 ∗ … … ∗ a k b k n=a1^{b1}*a2^{b2}*a3^{b3}*……*ak^{bk} n=a1b1∗a2