zoukankan      html  css  js  c++  java
  • 【bzoj4916】神犇和蒟蒻 杜教筛

    Description

    很久很久以前,有一只神犇叫yzyrsw;

    很久很久之后,有一只蒟蒻叫ltycky;

    Input

    请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;

    Output

    请你输出一个整数(A=sum_{i=1}^N{mu (i^2)});

    请你输出一个整数(B=sum_{i=1}^N{varphi (i^2)});

    Sample Input

    1

    Sample Output

    1
    1

    Sol

    第一问就是搞笑的,直接puts("1");

    第二问其实也不难,只要掌握一个技巧:把约数限制转化成上界限制(莫比乌斯反演大多数都是这样的)

    首先根据欧拉函数的定义,(varphi(i^2)=varphi(i)*i),原因是如果不是新的质因子那么贡献是p,新的质因子贡献是p-1,那么第二个i产生的贡献就全部都是p了,(prod{p}=i)

    然后继续推式子:

    (F(n)=sum_{i=1}^{n}i*varphi(i))

    这一步比较神:设(G(n)=n),那么F和G的狄利克雷卷积就是(sum_{i=1}^{n}sum_{d|i}varphi(d)*d*frac{i}{d}=sum_{i=1}^{n}i^2=n*(n+1)*(2n+1)/6)

    对于这个卷积式子,我们更换求和指标,消去约数限制,得:

    (sum_{i=1}^{n}sum_{d|i}varphi(d)*d*frac{i}{d}=sum_{d=1}^{n}sum_{i=1}^{lfloorfrac{n}{d} floor}i*varphi(i)*d)

    如果这一步把后面的i和d弄反了,其实转过来是等价的。

    之后原式(=sum^{n}_{d=1}d*F(lfloorfrac{n}{d} floor))

    (S(n)=sum_{i=1}^{n}i^2),则(S(n)=sum_{d=1}^{n}d*F(lfloorfrac{n}{d} floor))

    (S(n)=sum_{d=2}^{n}d*F(lfloorfrac{n}{d} floor)+F(n))

    (F(n)=S(n)-sum_{d=2}^{n}d*F(lfloorfrac{n}{d} floor))

    杜教筛标准形式。

    Code

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int n,phi[1000005],pri[1000005],vis[1000005],tot;map<ll,ll>mmp;ll P=6000000042ll,sum[1000005];
    ll s1(int l,int r){return 1ll*(l+r)*(r-l+1)%P/2;}
    ll s2(int x){return 1ll*x*(x+1)%P*(2*x+1)%P/6;}
    ll djs(int x)
    {
        if(x<=1000000) return sum[x];
        if(mmp.count(x)) return mmp[x];
        ll ans=s2(x),ls=0;
        for(int i=2;i<=x;i=ls+1) ls=x/(x/i),ans=(ans-1ll*s1(i,ls)*djs(x/i)%P+P)%P;
        mmp[x]=ans;return ans;
    }
    int main()
    {
        phi[1]=sum[1]=1;
        for(int i=2;i<=1000000;i++)
        {
            if(!vis[i]){pri[++tot]=i;phi[i]=i-1;}
            for(int j=1;j<=tot&&i*pri[j]<=1000000;j++)
            {
                vis[i*pri[j]]=1;
                if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
                phi[i*pri[j]]=phi[i]*(pri[j]-1);
            }
            sum[i]=(sum[i-1]+1ll*i*phi[i]%P)%P;
        }
        scanf("%d",&n);printf("1
    %d
    ",djs(n)%1000000007);
    }
    
  • 相关阅读:
    jquery 内容选择器
    jquery 子选择器
    jquery 基础选择器
    jquery 基础过滤器
    jdk1.8+SpringAOP注解报java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut select错误的不知原因的解决办法[仅供参考]
    [Spring]@Autowired,@Required,@Qualifier注解
    [Spring]IOC控制反转和DI依赖注入
    [LeetCode]无重复字符的最长子串
    Spring-代理模式
    Spring-使用注解开发
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/9398470.html
Copyright © 2011-2022 走看看