线性筛法
[介绍]
今天特地学了下线筛,感觉棒棒哒。。。线性筛法,顾名思义,就是每个数筛一遍,即每个合数只标记一
次,我们知道,一个合数可以写成一个素数和一个数的乘积的形式,而要想每个数筛一遍,需要找到每个数
的独特之处,每个合数都有唯一的最小质因数,这样我们筛t这个数时确保枚举的素数p是t的最小质因数即
可,每这样个合数都有最小质因数,这样所有合数都可以筛掉,又每个合数只有唯一确定的最小质因数,因
此每个合数只被筛一次,这是大致思想,根据下面的代码理解一下
#include<cstdio>
using namespace std;
const int maxnp = 1000000;
bool isp[maxnp];
int prime[maxnp];
int number = 0;
int main()
{
for(int i = 2; i <= maxnp; i++)
{
if(!isp[i])
prime[number++] = i;
for(int j = 0; j < number && i*prime[j] <= maxnp; j++)
{
isp[i*prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}
[思考]
通过枚举素数p与数k的乘积来筛数(废话…..),关键会如何确保要筛掉的数(p*k)的最小质因子是p呢?只要
确保k中不含有比p小的质因子就可以了啊。
if (i % prime[j] == 0) break;
当i中含有prime[j]这个因子时,k* prime[j + 1]、k*prime[j + 2]等等都不在合法了,因为他们的最小质因
子应该是primej[j + 1]、prime[j + 2]
最大公约数
[吐槽]
gcd(a,b)常写作(a,b), 满足(a,b)=(a+k*b,b)
int gcd(int a, int b)
{
if (!b)
return a;
return gcd(b, a % b);
}
快速幂
[介绍]3^
快速幂的思想实际上就是把b写成二进制的形式,即:
a^13=a^1101=a^(8 + 4 + 1)=a^8 * a^4 * a
然后对于a^1、a^2、a^4、a^8等便可以通过logb的复杂度自身相乘出来
int quick(int a, int b)
{
int ans = 1;
while (b)
{
if (b & 1)
ans *= a;
a *= a;
b /= 2;
}
return ans;
}