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

    Description:

    求$sumlimits_{i=1}^{n} sumlimits_{j=1}^{n} d(i imes j)$

    $d(i)$表示$i$的约数个数和。$n leq 10^9$

    废话:

    好久没有做反演了感觉自己都不会了。。。

    做了一遍发现自己真的不会了

    手推了不知道多久终于推出了式子中间还错了一遍打了一半发现过不去样例

    题解:

    标签都知道了那也就没什么好说的了,直接上式子(类比《约数个数和》那道题)(以下分数皆表示整除向下取整)

    $sumlimits_{i=1}^{n} sumlimits_{j=1}^{n} d(i imes j)$

    $=sumlimits_{i=1}^{n} sumlimits_{j=1}^{n} sumlimits_{a|i} sumlimits_{b|j} [gcd(a,b)==1] $

    $=sumlimits_{i=1}^{n} sumlimits_{j=1}^{n} sumlimits_{a|i} sumlimits_{b|j} sumlimits_{d|a   and   d|b} mu (d) $

    $=sumlimits_{d=1}^{n} mu (d) sumlimits_{a=1}^{frac{n}{d}} sumlimits_{b=1}^{frac{n}{d}} frac{frac{n}{d}}{a} frac{frac{n}{d}}{b}$

    $=sumlimits_{d=1}^{n} mu (d) (sumlimits_{i=1}^{frac{n}{d}} frac{frac{n}{d}}{i})^2$

    然后第二个$sum$后面的东西视作函数$f(frac{n}{d})$,可以整除分块,前面就是杜教筛得到$mu$的前缀和

    然后函数$f(frac{n}{d})$的求值其实也就是一个整除分块。

    其实$f(x)=sumlimits_{i=1}^{x} d(i)$即$sumlimits_{i=1}^{x} d(i) =sumlimits_{i=1}^{x} frac{x}{i}$

    这里的$d(x)$函数也是约数个数的意思。%%%LrefraiNC

    从含义上也可以理解。所以$f(x)$函数也可以杜教筛。但是我还没有做过$d(i)$的杜教筛所以我没有打。

    杜教筛线筛预处理的范围应该在$n^{frac{2}{3}}=10^6$不然慢的要死(虽说没有T)

     1 #include<cstdio>
     2 #define mod 1000000007
     3 struct hash_map{
     4     int w[10000005],fir[3000005],l[10000005],to[10000005],cnt;
     5     int &operator[](int x){
     6         int r=x%3000001;
     7         for(int i=fir[r];i;i=l[i])if(to[i]==x)return w[i];
     8         l[++cnt]=fir[r];fir[r]=cnt;to[cnt]=x;return w[cnt]=-123456789;
     9     }
    10 }M;
    11 int p[1000005],mu[1000005],pc;char np[1000005];
    12 int sum(int n){
    13     if(n<=1000000)return mu[n];
    14     if(M[n]!=-123456789)return M[n];
    15     int a=1;
    16     for(int l=2,r,A;l<=n;l=r+1)A=n/l,r=n/A,a-=sum(A)*(r-l+1);
    17     return M[n]=a;
    18 }
    19 long long cal(int x,long long ans=0){
    20     for(int l=1,r,a;l<=x;l=r+1)a=x/l,r=x/a,ans=(ans+a*(r-l+1ll))%mod;
    21     return ans*ans%mod;
    22 }
    23 int main(){
    24     mu[1]=1;
    25     for(int i=2;i<=1000000;++i){
    26         if(!np[i])p[++pc]=i,mu[i]=-1;
    27         for(int j=1;j<=pc&&i*p[j]<=1000000;++j)
    28             if(i%p[j])mu[i*p[j]]=-mu[i],np[i*p[j]]=-1;
    29             else np[i*p[j]]=-1;
    30         mu[i]+=mu[i-1];
    31     }
    32     int n;long long ans=0;scanf("%d",&n);
    33     for(int l=1,r,a;l<=n;l=r+1)a=n/l,r=n/a,ans+=1ll*cal(a)*(sum(r)-sum(l-1))%mod;
    34     printf("%lld
    ",(ans%mod+mod)%mod);
    35 }
    View Code
  • 相关阅读:
    【习题 3-12 UVA
    【习题 3-9 UVA
    【Codeforces Round #299 (Div. 2) E】Tavas and Pashmaks
    分布式ID生成器的解决方案总结
    Spring MVC表单防重复提交
    Spring import配置文件使用占位符
    什么是灰度发布,灰度测试。
    浅析负载均衡的6种算法,Ngnix的5种算法。
    神器,阿里巴巴Java代码检查插件
    去BAT面试完的Mysql面试题总结(55道,带完整答案)
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11760005.html
Copyright © 2011-2022 走看看