一 素数
1.判断一个数是不是素数 如果x<=1 则不是素数 是素数返回true 不是则返回false
bool is_pri(ll x) //时间复杂度O(√n)
{
ll s=sqrt(x+0.5); //加0.5是为了防止精度误差
for(ll i=2;i<=s;i++)
if(!(x%i)) return false;
return true;
}
bool is_pri(ll x) //时间复杂度O(√n)
{
for(ll i=2;i*i<=x;i++) //不用sqrt()来确定最大值 避免精度误差
if(!(x%i)) return false;
return true;
}
2.素数筛选法 找出1-n的所有素数
埃筛 : 埃拉托斯特尼筛法,或者叫埃氏筛法
原理 : 一个素数的倍数不是素数
const int N=1e6+7;
int vis[N]={0}; //vis[i]=0 i为素数 vis[i]=1 i不为素数
void prime() //时间复杂度 O(nloglogn)
{
vis[0]=1;
vis[1]=1;
for(int i=2;i<N;i++)
if(!vis[i])
for(int j=2*i;j<N;j+=i)
vis[j]=1;
}
埃筛优化
void prime()
{
vis[0]=1;
vis[1]=1;
for(int i=2;i*i<N;i++)
if(!vis[i])
for(int j=i*i;j<N;j+=i)
vis[j]=1;
}
二 快速幂
1.求x^y
(1)
const ll mod=1e9+7;
ll quick(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y%2) ans=(ans*x)%mod;
x=(x*x)%mod;
y/=2;
}
return ans;
}
(2)位运算形式
ll quick(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
(3) 衍生 快速乘
ll quick_mul(ll x,ll y)
{
ll ans=0;
while(y)
{
if(y&1) ans=(ans+x)%mod;
x=(x+x)%mod;
y>>=1;
}
return ans;
}
三gcd lcm
algorithm 里面有__gcd(a,b)内置函数
gcd原理 辗转相除法
ll gcd(ll a,ll b)
{
ll tmp;
while(b)
{
tmp=b;
b=a%b;
a=tmp;
}
return a;
}
gcd 衍生:
(1) lcm(a,b)=a/gcd(a,b)*b; //先除后乘 避免乘法溢出
(2) gcd(k*a,k*b)=k*gcd(a,b);
(3) lcm(k*a,k*b)=k*lcm(a,b);
推导lcm(k*a,k*b)=(k*a)/(k*gcd(a,b))(k*b)=k(a/gcd(a,b)*b)=k*lcm(a,b);
(4)除法:lcm(S/a,S/b)=S/gcd(a,b);