复习数论

线性筛

int P[Max],cnt;
bool vis[Max];
int GetP(int n)
{
    pos(i,1,n) vis[i]=true;
    vis[1]=false;
    pos(i,2,n)
    {
        if(vis[i])  P[++cnt]=i;
        for(int j=1;j<=cnt && i*P[j]<=n;j++)
        {
            vis[i*P[j]]=false;
            if(i%P[j]==0) break;
        }
    }
}

欧拉函数

单个数

\(𝜓(𝑎)=\prod_{i=1}^n 𝜓({𝑝_i}^{k_i})=\prod_{i=1}^n{𝑝_i}^{k_i}\prod_{i=1}^n (1-\frac{1}{p_i}) =a\prod_{i=1}^n(1-\frac{1}{p_i})\)

\(O(\sqrt n)\)可求出

int phi(int x)
{
    int ans=x;
    pos(i,2,sqrt(x))
    {
        if(n%i==0) 
        {
            ans=ans/i*(i-1);//先除后乘防止爆int
            while(n%i==0)n/=i;//筛去互质因子的幂次
        }
    }
    if(n>1) ans=ans/n*(n-1);//最后可能有剩余
    return ans;
}

线性筛求欧拉函数

\(𝜓(𝑎)=\prod_{i=1}^n 𝜓({𝑝_i}^{k_i})=\prod_{i=1}^n{𝑝_i}^{k_i}\prod_{i=1}^n (1-\frac{1}{p_i}) =a\prod_{i=1}^n(1-\frac{1}{p_i})\)
\(O(n)\)

int P[Max],Phi[Max],cnt;
bool vis[Max];
void Euler(int n)
{
    pos(i,1,n) vis[i]=true;
    vis[1]=false;
    pos(i,2,n)
    {
        if(vis[i])  P[++cnt]=i,Phi[i]=i-1;
        for(int j=1;j<=cnt && i*P[j]<=n;j++)
        {
            vis[i*P[j]]=false;
            if(i%P[j]==0) 
            {
                Phi[i*P[j]]=Phi[i]*P[j];//如果因子已经参与运算,相当于只改变上式的a
                break;
            }
            else Phi[i*P[j]]=Phi[i]*(P[j]-1);//第一次参与,乘p*(1-1/p)
        }
    }
}

posted @ 2021-11-04 12:15  juuich  阅读(31)  评论(0编辑  收藏  举报