一 素數
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);