筛法&快速幂&容斥原理
>>筛法
埃氏筛法
筛质数求1~n间的质数个数
const int N=1000010;
int n,primes[N],cnt; //primes[]记录质数 cnt记录质数个数
bool st[N]; //来标记它是质数还是合数,初始化为0即为false规定为质数
using namespace std;
void get_primes(int n)
{
for(int i =2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i; //如果是质数把它加到数组里去
//是合数的话就不用管
}
for(int j = i+i;j<=n;j+=i) st[j]=true;//再把它所有的倍数标记为合数
}
//优化 for循环放里边
void get_primes(int n)
{
for(int i =2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i; //如果是质数把它加到数组里去
//是合数的话就不用管
for(int j = i+i;j<=n;j+=i) st[j]=true; //再把它所有的倍数标记为合数
}//优化部分,把质数的倍数标记了
}
欧拉筛法(一般使用这种方法,因为在10^6以上它更快)
用某个数的最小质因子删除它,由于最小质因子是唯一的,所以就不会出现重复删除一个数的情况
const int N = 1000010;
int n, primes[N], cnt;
bool st[N];
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i]) primes[cnt++] = i;
for(int j = 0; primes[j] <= n / i; j++) //枚举所有<=它的质数
{
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;//直到找到i的最小质因子退出循环
}
}
}
>>快速幂
用来求解a^b%p的问题
采用二进制进行优化
eg:
代码如下:
typedef long long LL;
int qmi(int a, int k, int p)
{
int res = 1;
while(k)
{
if(k & 1) res = (LL)res * a % p; //即与1相与k&==1
k >>= 1; //k右移一位
a = (LL)a * a % p;
}
return res;
}
>>容斥原理
维护集合的思想