• 51Nod1220 约数之和


    51Nod 1220 - 约数之和 

    类比约数个数和那个题

    如果知道:

    然后枚举约数,枚举gcd,用miu代替,大力反演一波

    得到:

    后面那个平方,其实是约数和的前缀和。线性筛预处理一部分,剩下的根号求解

    前面的miu*i,杜教筛。

    有意思的是:另一边推下来得到:(从右往左看)

    然后就凑成了那个平方。

    Code;

    记得sum是:n*(n+1)/2

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define int long long
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    template<class T>il void ot(T x){x/10?ot(x/10):putchar(x%10+'0');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) printf("%lld ",a[i]);putchar('
    ');}
    
    namespace Miracle{
    const int N=1e6+6;
    const int mod=1e9+7;
    int n;
    int vis[N],miu[N];
    ll sig[N];//miu  :  miu(i)*i and pre 
    //sig : pre
    int div[N];
    int pri[N],tot;
    int ad(int x,int y){
        return x+y>=mod?x+y-mod:x+y;
    }
    int sub(int x,int y){
        return x-y<0?x-y+mod:x-y;
    }
    void sieve(int n){
        miu[1]=1;sig[1]=1;
        div[1]=1;
        for(reg i=2;i<=n;++i){
            if(!vis[i]){
                pri[++tot]=i;
                miu[i]=-1;sig[i]=i+1;
                div[i]=i+1;
            }
            for(reg j=1;j<=tot;++j){
                if(i*pri[j]>n) break;
                vis[i*pri[j]]=1;
                if(i%pri[j]==0){
                    miu[i*pri[j]]=0;
                    sig[i*pri[j]]=sig[i]/div[i]*(div[i]*pri[j]+1);
                    div[i*pri[j]]=div[i]*pri[j]+1;
                    break;
                }
                miu[i*pri[j]]=-miu[i];
                sig[i*pri[j]]=sig[i]*sig[pri[j]];
                div[i*pri[j]]=pri[j]+1;
            }
        }
        for(reg i=1;i<=n;++i){
            miu[i]=ad((ll)i*ad(mod,miu[i])%mod,miu[i-1]);
            sig[i]%=mod;
            sig[i]=ad(sig[i],sig[i-1]);
        }
    }
    int Sum(int n){
        return (ll)n*(n+1)/2%mod;
    }
    int Sig(int n){
        if(n<N-5) return sig[n];
        int ret=0;
        for(reg i=1,x=0;i<=n;i=x+1){
            x=(n/(n/i));
            ret=ad(ret,(ll)sub(Sum(x),Sum(i-1))*(n/i)%mod);
        }
        return ret;
    }
    const int G=31630;
    map<int,int>mp;
    int sol(int n){
        if(n<=N-5) return miu[n];
        if(mp[n]) return mp[n];
        int ret=1;
        for(reg i=2,x=0;i<=n;i=x+1){
            x=(n/(n/i));
            ret=sub(ret,(ll)sub(Sum(x),Sum(i-1))*sol(n/i)%mod);
        }
        return mp[n]=ret;
    }
    int main(){
        rd(n);
        sieve(N-5);
        ll ans=0;
    //    memset(p,-1,sizeof p);
        for(reg d=1,x=0;d<=n;d=x+1){
            x=n/(n/d);
            ll tmp=Sig(n/d);
            tmp=tmp*tmp%mod;
            ans=ad(ans,(ll)sub(sol(x),sol(d-1))*tmp%mod);
        }
        printf("%lld",ans);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/8 14:52:26
    */
  • 相关阅读:
    如何使用Linux命令实时查看最新的日志信息
    什么是缺陷(bug)
    APP 崩溃测试点小结
    软件测试之权限测试
    web安全测试之 xss攻击
    URL详谈
    随机生成名字或短句代码机
    JAVA环境变量配置
    Properties类与读取properties文件
    JAVA 打印九九乘法表
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10496258.html
Copyright © 2020-2023  润新知