zoukankan      html  css  js  c++  java
  • [LOJ124] 除数函数求和 1

    Description

    给定 (n le 10^7,k),求 (sum_{i=1}^n sigma_k (i)),其中 (sigma_k(n)=sum_{d|n} d^k)

    Solution

    自然想到交换求和顺序,即

    [sum_{i=1}^n sigma_k(i) =sum_{i=1}^n sum_{d|i} d^k=sum_{i=1}^n[frac n i]i^k ]

    于是,不妨设 (f(i)=i^k),则我们可以对每个 (f(i))(O(log n)) 时间内计算,故总时间复杂度为 (O(nlog n))。由于评测机很快,这样已经能卡过去了。

    考虑到 (f(i)) 是完全积性的,我们可以分出 (i) 对最小素因子 (p_i),利用线性筛计算所有合数的 (f(i))。这样复杂度为 (O(n+frac n {log n} log n)=O(n)),可以接受。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 10000005;
    const int mod = 1e9+7;
    
    int isp[N],vp[N],f[N],pcnt,n,k,ans;
    
    int qpow(int p,int q)
    {
        return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n>>k;
    
        for(int i=2;i<=n;i++)
        {
            isp[i]=1;
        }
        for(int i=2;i<=n;i++)
        {
            if(isp[i])
            {
                vp[++pcnt]=i;
                f[i]=qpow(i,k);   
            }
            for(int j=1;j<=pcnt&&vp[j]*i<=n;j++)
            {
                isp[i*vp[j]]=0;
                f[i*vp[j]]=f[i]*f[vp[j]]%mod;
                if(i%vp[j]==0) break;
            }
        }
        for(int i=1;i<=n;i++)
        {
            ans=(ans+(n/i)*f[i]%mod)%mod;
        }
        cout<<(ans+n)%mod<<endl;
        //system("pause");
    }
    
  • 相关阅读:
    騎士宣言
    [洛谷P1631] 序列合并
    [HNOI2006]公路修建问题
    [洛谷2068] 统计和
    [洛谷P1168] 中位数
    【模板】可持久化数组(可持久化线段树/平衡树)
    【模板】可持久化线段树 1(主席树)
    [JSOI2008]最大数maxnumber
    NOI导刊2010提高(06) 黑匣子
    [洛谷1533] 可怜的狗狗
  • 原文地址:https://www.cnblogs.com/mollnn/p/13683419.html
Copyright © 2011-2022 走看看