zoukankan      html  css  js  c++  java
  • BZOJ 3994 约数个数和

    莫比乌斯反演?不知道有没有用到。

    原式=∑(x=1...n)μ(x)∑(i=1..[n/x])d(i)∑(j=1..[m/x])d(j)。

    对miu,d分别前缀和,再对d*d进行分块。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define maxn 50010
    using namespace std;
    long long miu[maxn],prime[maxn],e[maxn],k[maxn],pre[maxn],cnt=0,premiu[maxn];
    long long tk,n,m;
    bool vis[maxn];
    void get_prime()
    {
    memset(vis,false,sizeof(vis));
    e[1]=1;k[1]=1;miu[1]=1;
    for (long long i=2;i<=maxn-5;i++)
    {
    if (vis[i]==false)
    {
    prime[++cnt]=i;
    e[i]=1;k[i]=2;
    miu[i]=-1;
    }
    for (long long j=1;j<=cnt && i*prime[j]<=maxn-5;j++)
    {
    vis[i*prime[j]]=true;
    if (i%prime[j]==0)
    {
    k[i*prime[j]]=k[i]/(e[i]+1)*(e[i]+2);
    e[i*prime[j]]=e[i]+1;
    miu[i*prime[j]]=0;
    }
    else
    {
    k[i*prime[j]]=k[i]*k[prime[j]];
    e[i*prime[j]]=1;
    miu[i*prime[j]]=-miu[i];
    }
    }
    }
    pre[1]=k[1];premiu[1]=1;
    for (long long i=2;i<=maxn-5;i++)
    {
    pre[i]=pre[i-1]+k[i];
    premiu[i]=premiu[i-1]+miu[i];
    }
    }
    void work()
    {
    scanf("%lld%lld",&n,&m);
    if (n>m) swap(n,m);
    long long ans=0,r=1;
    while (r<=n)
    {
    long long j=min((n/(n/r)),(m/(m/r)));
    ans=ans+(premiu[j]-premiu[r-1])*pre[n/r]*pre[m/r];
    r=j+1;
    }
    printf("%lld ",ans);
    }
    int main()
    {
    scanf("%lld",&tk);
    get_prime();
    for (long long i=1;i<=tk;i++)
    work();
    return 0;
    }

  • 相关阅读:
    洛谷
    洛谷
    洛谷
    模板
    洛谷
    洛谷
    Codeforces Round #561 (Div. 2) E. The LCMs Must be Large(数学)
    Codeforces Round #561 (Div. 2)
    Mail.Ru Cup 2018 Round 2 C. Lucky Days(拓展欧几里得)
    The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5170140.html
Copyright © 2011-2022 走看看