素数 快速幂 gcd.lcm

来源:互联网 发布:泰安中商网络 编辑:程序博客网 时间:2024/05/17 04:07

一 素数

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

原创粉丝点击