• 数学:莫比乌斯反演-约数个数和


    BZOJ3994:利用莫比乌斯反演求约数个数和

    解答此题需要利用约束个数函数的形式,将其与gcd联系再一起,然后再反演,推导

    很麻烦

     1 #include<cstdio>
     2 #include<algorithm>
     3 using std::min;
     4 const int maxn=50005;
     5 int cnt;
     6 long long ans=0;
     7 bool vis[maxn];
     8 int mu[maxn],sum[maxn];
     9 long long prim[maxn],g[maxn];
    10 inline long long read()
    11 {
    12     long long x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 void get_mu(int n)
    18 {
    19     mu[1]=1;
    20     for(int i=2;i<=n;i++)
    21     {
    22         if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
    23         for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
    24         {
    25             vis[prim[j]*i]=1;
    26             if(i%prim[j]==0) break;
    27             else mu[i*prim[j]]=-mu[i];
    28         }
    29     }
    30     for(int i=1;i<=n;i++) sum[i]=sum[i-1]+mu[i];
    31     for(int i=1;i<=n;i++)
    32     {
    33         for(int l=1,r;l<=i;l=r+1)
    34         {
    35             r=(i/(i/l));
    36             g[i]+=(long long)(r-l+1)*(long long)(i/l);
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     int T,n,m,max_rep;
    43     T=read();
    44     get_mu(50000);
    45     while(T--)
    46     {
    47         ans=0;
    48         n=read();m=read();
    49         max_rep=min(n,m);
    50         for(int l=1,r;l<=max_rep;l=r+1)
    51         {
    52             r=min(n/(n/l),m/(m/l));
    53             ans+=(sum[r]-sum[l-1])*(long long)g[n/l]*(long long)g[m/l];
    54         }
    55         printf("%lld
    ",ans);
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    Oracle分析函数
    oracle row_number的使用
    lru缓存测试类
    注解测试类
    lucene测试类
    SVN中检出(check out) 跟导出(export) 的区别
    Lucene原理与代码分析
    Lucene入门基础教程
    linux的less命令
    day4 大纲笔记
  • 原文地址:https://www.cnblogs.com/aininot260/p/9702622.html
Copyright © 2020-2023  润新知