zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    【POJ 3162】 Walking Race (树形DP-求树上最长路径问题,+单调队列)
    【POJ 2152】 Fire (树形DP)
    【POJ 1741】 Tree (树的点分治)
    【POJ 2486】 Apple Tree (树形DP)
    【HDU 3810】 Magina (01背包,优先队列优化,并查集)
    【SGU 390】Tickets (数位DP)
    【SPOJ 2319】 BIGSEQ
    【SPOJ 1182】 SORTBIT
    【HDU 5456】 Matches Puzzle Game (数位DP)
    【HDU 3652】 B-number (数位DP)
  • 原文地址:https://www.cnblogs.com/stranger-/p/10762784.html
Copyright © 2011-2022 走看看