• 51Nod 1237 最大公约数之和 V3 杜教筛


    题目链接http://www.51nod.com/Challenge/Problem.html#!#problemId=1237

    题意:求$sum_{i=1}^{n}sum_{j=1}^{n}gcd(i,j)$ ,$1leq{n}leq10^{10}$.

    知识提要:$n=sum_{d|n}varphi(d)$ 该公式证明https://blog.csdn.net/chen1352/article/details/50695930

    根据莫比乌斯反演可以得到 $varphi(n)=sum_{d|n}mu(frac{n}{d})d$

    解析:试着化简这个柿子,枚举最大公因数d

    $$ quadsum_{d=1}^{n}sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{n}{d} floor}[(i,j)=1]d\$$

    $$=sum_{d=1}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{n}{d} floor}[(i,j)=1]$$

    右边根据莫比乌斯反演化简

    $$sum_{d=1}^{n}dsum_{d'=1}^{lfloorfrac{n}{d} floor}mu(d')lfloor{frac{n}{dd'}} floorlfloor{frac{n}{dd'}} floor$$

    令T=dd'

    $$sum_{T=1}^{n}lfloor{frac{n}{T}} floorlfloor{frac{n}{T}} floorsum_{d|T}mu(frac{T}{d})d$$

    把右边替换成$varphi(T)$得到

    $$sum_{T=1}^{n}lfloor{frac{n}{T}} floorlfloor{frac{n}{T}} floorvarphi(T)$$

    所以求出来欧拉函数的前缀和 这个式子也就求出来了

    AC代码

    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(a) (a).begin(), (a).end()
    #define fillchar(a, x) memset(a, x, sizeof(a))
    #define huan printf("
    ");
    #define debug(a,b) cout<<a<<" "<<b<<" ";
    using namespace std;
    const int maxn=1e6+10,inf=0x3f3f3f3f;
    typedef long long ll;
    const ll mod = 1000000007;
    typedef pair<int,int> pii;
    int check[maxn],prime[maxn],phi[maxn],sum[maxn];
    void Phi(int N)//莫比乌斯函数线性筛
    {
        int pos=0;sum[0]=0;
        sum[1]=phi[1]=1;
        for(int i = 2 ; i <= N ; i++)
        {
            if (!check[i])
                prime[pos++] = i,phi[i]=i-1;
            for (int j = 0 ; j < pos && i*prime[j] <= N ; j++)
            {
                check[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]*(prime[j]-1);
            }
            sum[i]=(sum[i-1]+phi[i])%mod;
        }
    }
    unordered_map<ll,ll> ma;
    ll inv2=500000004;
    ll solve(ll n)
    {
        if(n<=1e6)
            return sum[n];
        else if(ma.count(n))
            return ma[n];
        ll temp = ((n%mod)*((n+1)%mod)%mod)*inv2%mod;
        for(ll i=2,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            temp = (temp-solve(n/i)*(j-i+1)%mod+mod)%mod;
        }
        return ma[n]=temp;
    }
    int main()
    {
        ll n;
        Phi(1e6);
        scanf("%lld",&n);
        ll ans=0;
        for(ll i=1,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            ll k=(n/i)%mod;
            k = k*k%mod;
            ll temp=((solve(j)-solve(i-1)+mod)%mod)*k%mod;
            ans=(ans+temp)%mod;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    Python 42 mysql用户管理 、pymysql模块
    Python 41 多表查询 和 子查询
    Python 41 完整查询语句 和 一堆关键字
    Python 40 数据库-外键约束 、多对一与多对多的处理
    Python 40 数据库-约束
    Python 38 注册和修改密码
    eas之关于编码规则
    eas之界面之间传递参数
    eas之获取集合
    eas之单据删除代码
  • 原文地址:https://www.cnblogs.com/stranger-/p/10762784.html
Copyright © 2020-2023  润新知