1.欧几里得求最大公约数

int _gcd(int x,int y)
{
    return y?_gcd(y,x%y):x;
}

2.最小公倍数

#include <bits/stdc++.h>
using namespace std;
int gcd(int x,int y)
{
    return y?gcd(y,x%y):x;
}
int main()
{
    int n,a;
    while(scanf("%d",&n)!=EOF)
    {
        int ans=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            ans=ans/gcd(ans,a)*a;//注意先除后乘
        }
        printf("%d\n",ans);
    }
    return 0;
}

3.素因子分解( 复杂度:sqrt(n) )
当n比较大时,可以先用欧拉筛筛出sqrt(n)范围内的素数,然后把for循环里面的i换成对素数的遍历。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int factor[N],e[N];//factor[]:用来存素因子个数,(可以用vector代替)e[]:用来存对应的素因子的幂
int divide(int num)
{
    int tn=num,cnt=0;
    memset(e,0,sizeof(e));
    for(int i=2;i*i<=num;i++)//sqrt(n)的复杂度
    {
        if(tn%i==0)
        {
            factor[++cnt]=i;
            while(tn%i==0)
            {
                e[cnt]++;
                tn/=i;
            }
        }
    }
    if(tn>1)//不能省略!
    {
        factor[++cnt]=tn;
        e[cnt]++;
    }
    return cnt;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int cot=divide(n);
        printf("%d:",n);
        for(int i=1;i<=cot;i++)//输出各个素因子
        {
            while(e[i]--)//幂
                printf(" %d",factor[i]);
        }
        puts("");
    }
    return 0;
}

4.快速幂取模
函数里面的数据类型都用long long 容易爆int

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll POW(ll x,ll y)
{
    ll res=1;
    while(y)
    {
        if(y&1)
            res=res*x%mod;//易爆int
        x=x*x%mod;//易爆int
        y>>=1;
    }
    return res%mod;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        printf("%lld\n",POW((ll)m,(ll)n));//int会超数据范围
    }
    return 0;
}

5.求一个数的欧拉函数值
数据复杂度:sqrt(n)

#include <bits/stdc++.h>
using namespace std;
int phi(int num)
{
    int res=num;
    for(int i=2;i*i<=num;i++)
    {
        if(num%i==0)
        {
            res-=(res/i);
            while(num%i==0)
                num/=i;
        }
    }
    if(num>1)
        res-=(res/num);
    return res;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",phi(n));
    }
    return 0;
}

6.欧拉筛筛 N 以内的素数
时间复杂度:O(n)

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
bool vis[N];//标记非素数
vector<int>prime;//保存素数
void euler()
{
    prime.clear();
    memset(vis,0,sizeof(vis));
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
            prime.push_back(i);
        for(int j=0;j<prime.size()&&i*prime[j]<N;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    euler();
    
    return 0;
}

7.欧拉筛筛 N 以内的所有数的欧拉函数值
时间复杂度:O(n)

const int N=1e5+5;
int phi[N];//存欧拉函数值
bool vis[N];//标记非素数
vector<int>prime;//存素数
void euler()
{
    memset(vis,0,sizeof(vis));
    //memset(phi,0,sizeof(phi));
    prime.clear();
    phi[1]=1;//预处理phi[1]
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
        {
            prime.push_back(i);
            phi[i]=i-1;//素数的欧拉函数值的性质
        }
        for(int j=0;j<prime.size()&&i*prime[j]<N;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else
                phi[i*prime[j]]=phi[i]*phi[prime[j]];//积性函数的性质
        }
    }
}

8.欧拉筛筛莫比乌斯函数值
时间复杂度:O(n)

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
vector<int>prime;
int mob[N];
bool vis[N];
void mobius()
{
    prime.clear();
    memset(vis,0,sizeof(vis));
    mob[1]=1;//莫比乌斯函数第一类情况
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
        {
            prime.push_back(i);
            mob[i]=-1;//素数
        }
        for(int j=0;j<prime.size()&&prime[j]*i<N;j++)
        {
            int tmp=i*prime[j];
            vis[tmp]=1;
            if(i%prime[j]==0)
            {
                mob[tmp]=0;//其他情况,因为prime[j]是i的因子,所以k的因子中含有的prime[j]的个数不是1
                break;
            }
            else
               mob[tmp]=-mob[i];//积性函数的性质
        }
    }
}
int main()
{
    mobius();
    for(int i=1;i<=10;i++)
        cout<<mob[i]<<endl;
    return 0;
}