zoukankan      html  css  js  c++  java
  • bzoj 4176: Lucas的数论 -- 杜教筛,莫比乌斯反演

    4176: Lucas的数论

    Time Limit: 30 Sec  Memory Limit: 256 MB

    Description

    去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了。

    在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数。他现在长大了,题目也变难了。
    求如下表达式的值:
     
    其中 表示ij的约数个数。
    他发现答案有点大,只需要输出模1000000007的值。

    Input

    第一行一个整数n。

    Output

     一行一个整数ans,表示答案模1000000007的值。

    Sample Input

    2

    Sample Output

    8

    HINT

     对于100%的数据n <= 10^9。

     

    Source

    emmmm,转载一份题解吧,写的很清晰了 http://blog.csdn.net/clove_unique/article/details/67633389

    我们先反演一下,化简成这样

    然后就括号内的东西可以O(√n)算出,然后杜教筛出mu值,就可以了

    (复杂度不要问我qwq

    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define mod 1000000007
    #define ll long long
    #define N 1000555
    int mu[N],pri[N],tot;
    bool vs[N];
    void INIT()
    {
        mu[1]=1;
        for(int i=2;i<N;i++)
        {
            if(!vs[i]) pri[++tot]=i,mu[i]=-1;
            for(int j=1;j<=tot&&pri[j]*i<N;j++)
            {
                vs[pri[j]*i]=1;
                if(i%pri[j]==0){mu[pri[j]*i]=0;break;}
                mu[pri[j]*i]=-mu[i];
            }
            mu[i]+=mu[i-1];
        }
    }
    int n;
    ll ans;
    ll F(int x)
    {
        ll tp=0;
        for(int i=1,j;i<=x;i=j+1)
        {
            j=x/(x/i);
            (tp+=(ll)(x/i)*(j-i+1))%=mod;
        }
        return tp*tp%mod;
    }
    map<int,int>p;
    ll sol(int x)
    {
        if(x<N) return mu[x];
        if(p[x]) return p[x];
        ll ta=1;
        for(int i=2,j;i<=x;i=j+1)
        {
            j=x/(x/i);
            (ta-=sol(x/i)*(j-i+1))%=mod;
        }
        if(ta<0) ta+=mod;
        return p[x]=ta;
    }
    int main()
    {
        INIT();
        scanf("%d",&n);
        for(int i=1,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            (ans+=F(n/i)*(sol(j)-sol(i-1)+mod))%=mod;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    C++字符串转数字,数字转字符串
    [转]基础知识整理
    POJ 3071 Football
    POJ 3744 Scout YYF I
    2013成都Regional:一块木板,几个气球
    HDOJ 4497 GCD and LCM
    POJ 1185 炮兵阵地
    POJ 2031 Building a Space Station
    HDOJ 4717 The Moving Points
    CSU 1328: 近似回文词
  • 原文地址:https://www.cnblogs.com/lkhll/p/7880426.html
Copyright © 2011-2022 走看看