• HDU-5608:function


    HDU-5608:function

    题意:

    设函数(f(x))有:

    [N^2-3N+2=sum_{d|N}f(d) ]

    (sum_{i=1}^Nf(i))

    思路:

    设:

    [F(n)=sum_{d|n}f(d)=n^2-3n+2 ]

    反演得:

    [f(n)=sum_{d|n}mu(d)F(frac{n}{d}) ]

    求和:

    [sum_{i=1}^Nf(i)=sum_{i=1}^Nsum_{d|i}mu(d)F(frac{i}{d}) ]

    将枚举(i)改为枚举(id)

    [sum_{d=1}^Nmu(d)sum_{i=1}^{frac{N}{d}}F(i) ]

    我们可以发现前面的可以杜教筛一下,问题在于如何求后面的式子。

    [sum_{i=1}^Ni^2-3i+2 ]

    我们一项一项的拆开。

    首先有平方和求和公式,然后有等差数列求和公式,最后再加个(2n),那么这个问题就解决了。

    [sum=frac{n(n+1)(2n+1)}{6}-3frac{(n+1)(n)}{2}+2n ]

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 5e6;
    const int mod = 1e9+7;
    
    bool vis[maxn+10];
    int primes[maxn+10], cnt;
    ll mu[maxn+10];
    
    void init(int n)
    {
        mu[1] = 1;
        for(int i = 2; i <= n; i++)
        {
            if(!vis[i])
            {
                primes[++cnt] = i;
                mu[i] = -1;
            }
            for(int j = 1; primes[j] <= n/i; j++)
            {
                vis[primes[j]*i] = 1;
                if(i % primes[j] == 0) break;
                else mu[i*primes[j]] = -mu[i];
            }
        }
        for(int i = 1; i <= n; i++)
            mu[i] += mu[i-1], mu[i] %= mod;
    }
    
    unordered_map<ll, ll> Smu;
    inline ll getSmu(ll n)
    {
        if(n <= maxn) return mu[n];
        if(Smu[n]) return Smu[n];
        ll res = 1;
        for(ll l = 2, r; l <= n; l = r+1)
        {
            r = n/(n/l);
            res -= (r-l+1)%mod*getSmu(n/l)%mod;
            res = (res+mod)%mod;
        } return Smu[n] = res;
    }
    
    const ll inv6 = 166666668;
    const ll inv2 = 500000004;
    ll S(ll x)
    {
        ll res = 0;
        res += x*(x+1)%mod*(2*x+1)%mod*inv6%mod; res %= mod;
        res -= 3*(x+1)%mod*(x)%mod*inv2%mod;  res %= mod;
        res += 2*x%mod; res %= mod;
        return res;
    }
    
    ll n;
    void solve()
    {
        scanf("%lld", &n);
        ll ans = 0;
        for(ll l = 1, r; l <= n; l = r+1)
        {
            r = n/(n/l);
            ans += ((getSmu(r)-getSmu(l-1))%mod+mod)%mod*S(n/l)%mod;
            ans %= mod;
        }
        printf("%lld
    ", ans);
    }
    
    int main()
    {
        init(maxn);
        int T; scanf("%d", &T);
        while(T--) solve();
        return 0;
    }
    
    
  • 相关阅读:
    SVN为什么比Git更好
    vim的高亮查找操作
    Mac利用PD虚拟机安装Centos7
    学习MapReduce的计算原理
    hadoop-HA高可用集群部署
    HDFS命令操作和高可用
    初识hadoop及伪集群部署
    初步学习nginx
    小记--------maxwell启动失败解决
    小记--------spark资源调度机制源码分析-----Schedule
  • 原文地址:https://www.cnblogs.com/zxytxdy/p/12425864.html
Copyright © 2020-2023  润新知