zoukankan      html  css  js  c++  java
  • [luogu P2586] GCD 解题报告 (莫比乌斯反演|欧拉函数)

    题目链接:https://www.luogu.org/problemnew/show/P2568#sub

    题目大意:

    计算$sum_{x=1}^nsum_{y=1}^n [gcd(x,y)==prime]$

    题解:

    解法一:莫比乌斯反演套路题

    其实这样就可以了,但是还可以优化一下子

    ​T=dp

    整除分块就好了,其实这就和 yy的gcd 一样了

    解法二:欧拉函数

    考虑上面的第一个式子可以化简成

    tot是n以内质数的数量

    这是因为考虑到每次都两次计算了​$varphi(1)$

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    
    const int N=1e7+15;
    int n,tot;
    ll ans;
    int prime[5000000];
    ll phi[N];
    bool vis[N];
    void get_phi()
    {
        phi[1]=1;
        for (int i=2;i<=n;i++)
        {
            if (!vis[i]) {phi[i]=i-1;prime[++tot]=i;}
            for (int j=1;j<=tot&&i*prime[j]<=n;j++)
            {
                vis[i*prime[j]]=1;
                if (i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
                else 
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
            }
        }
        for (int i=2;i<=n;i++) phi[i]=phi[i-1]+phi[i];
    }
    int main()
    {
        scanf("%d",&n);
        get_phi();
        //for (int i=1;i<=n;i++) printf("%d ",phi[i]);
        for (int i=1;i<=tot;i++)
        {
            ans+=phi[n/prime[i]];
        }
        printf("%lld
    ",ans*2-tot);
        return 0;
    }
  • 相关阅读:
    裴蜀定理
    上下界网络流
    寻找符合子序列要求的区间个数
    小猪分配 , 最大流
    floyd + 最大流 (奶牛分配问题)
    抛硬币问题
    消消乐
    Entity Framework(1)
    冒泡排序
    二分法查找数据
  • 原文地址:https://www.cnblogs.com/xxzh/p/9646524.html
Copyright © 2011-2022 走看看