BZOJ 3994 Sdoi2015 约数个数和 莫比乌斯反演

该博客探讨了BZOJ 3994题目的解决方案,涉及数论中的一个重要结论:求所有整数对(i, j)的约数个数和。作者通过莫比乌斯反演证明了特定等式的正确性,并详细解释了每个质数对答案的贡献,展示了如何利用数论技巧解决这个问题。" 119281173,7800548,使用Plotly进行双坐标轴图表可视化,"['数据可视化', 'Python编程', '数据科学', '机器学习', '深度学习']
摘要由CSDN通过智能技术生成

题目大意:求 ni=1mj=1d(ij)
首先我们有一个很神的结论:
ni=1mj=1d(ij)=ni=1mj=1nimj[gcd(i,j)==1]
这个结论是怎么来的呢?我们可以先证明这个:
d(nm)=i|nj|m11[gcd(i,j)==1]
显然这个式子的前缀和就是上面的式子
现在我们来证明这个式子是对的
我们分开讨论每一个质数 p 对答案的贡献
不妨设n=npk1,m=mpk2
那么左式中 p 的贡献显然是k1+k2+1
右式中只考虑 p 的话,满足要求的数对(i,j)只有 (pk1,1),(pk11,1),...,(p,1),(1,1),(1,p),...,(1,pk21),(1,pk2) ,共有 k1+k2+1
因此等式成立,原式得证。
然后怎么搞还用我说么= =?

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 50500
using namespace std;

int n,m;

int mu[M],d[M],cnt[M],prime[M],tot;
bool not_prime[M];
void Linear_Shaker()
{
    int i,j;
    mu[1]=1;d[1]=1;
    for(i=2;i<=50000;i++)
    {
        if(!not_prime[i])
        {
            prime[++tot]=i;
            mu[i]=-1;
            d[i]=2;
            cnt[i]=1;
        }
        for(j=1;prime[j]*i<=50000;j++)
        {
            not_prime[prime[j]*i]=true;
            if(i%prime[j]==0)
            {
                mu[prime[j]*i]=0;
                d[prime[j]*i]=d[i]/(cnt[i]+1)*(cnt[i]+2);
                cnt[prime[j]*i]=cnt[i]+1;
                break;
            }
            mu[prime[j]*i]=-mu[i];
            d[prime[j]*i]=d[i]<<1;
            cnt[prime[j]*i]=1;
        }
    }
    for(i=1;i<=50000;i++)
    {
        mu[i]+=mu[i-1];
        d[i]+=d[i-1];
    }
}
long long Solve()
{
    long long re=0;
    int i,last;
    if(n>m) swap(n,m);
    for(i=1;i<=n;i=last+1)
    {
        last=min(n/(n/i),m/(m/i));
        re+=(long long)(mu[last]-mu[i-1])*d[n/i]*d[m/i];
    }
    return re;
}
int main()
{
    int T;
    Linear_Shaker();
    for(cin>>T;T;T--)
    {
        scanf("%d%d",&n,&m);
        printf("%lld\n",Solve());
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值