线性筛
线性筛的作用就是为了保证每个合数都只被其【最小的】那个质因数标记一次。

这下面👇讲的比较一般啊。
线性筛只有可能标记一个数字一次。

这个讲的有点复杂了,最后是关键,就是每个数只会以唯一方式被标记。
m=p1n=p1m1−1×p2m2×p3m3×⋯×pkmk
n 只会在遍历到 m 时被标记。
假设这个n,在遍历到 m 之前就被标记,假设该数字是 m‘,但是 m’×minp[m′]=n 是必须满足的条件,if(p==minp[i]) break; ,m‘ 只会标记到这个最小素因子*自身,因此 m’ 想标记 n,当且仅当 m’×minp[m′]=n。显然,m‘=m,得证。
https://qoj.ac/submission/995868
https://cp-algorithms.com/algebra/prime-sieve-linear.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
vector<ll> minp,primes; void sieve(ll n){ minp.assign(n+5,0); for(int i=2;i<=n;++i){ if(minp[i]==0){ minp[i]=i; primes.push_back(i); } for(auto p:primes){ if(i*p>n){ break; } minp[i*p]=p; if(p==minp[i]){ break; } } } }
|
使用线性筛的minp分解素因数更快,效率更高。
1 2 3 4 5 6 7
| vector<ll> prs; for(int j=W[i];j>1;j/=minp[j]){ ll p=minp[j]; prs.pb(p); } sort(all(prs)); prs.resize(unique(all(prs))-prs.begin());
|