素數 快速冪 gcd.lcm

一 素數

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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章