bzoj 3309: DZY Loves Math (反演)

26 篇文章 0 订阅

题目描述

传送门

题目大意:
定义 f(n) 表示n所含质因子的最大幂指数。
i=1nj=1mf(gcd(i,j))

题解

设n<=m

k=1nf(k)i=1nj=1n[gcd(i,j)=k]

k=1nf(k)d=1nμ(d)nkdnkd

中间具体的化简过程可以参照 bzoj 4407
T=kd
T=1nnTnTd|Tμ(Td)f(d)

这道题的关键就是求 d|Tμ(Td)f(d) ,而 f <script type="math/tex" id="MathJax-Element-538">f</script>显然不是积性函数,所以我们无法利用积性函数的性质进行计算。需要分析+乱搞。

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 10000000
#define LL long long 
#define p 1000000007
using namespace std;
int pd[N+3],prime[N+3],mu[N+3],g[N+3],cnt[N+3];
int n,m,T;
LL f[N+3];
void init()
{
    mu[1]=1;
    for (int i=2;i<=N;i++) {
        if (!pd[i]) {
            prime[++prime[0]]=i;
            mu[i]=-1; cnt[i]=1; g[i]=i; f[i]=1;
        }
        for (int j=1;j<=prime[0];j++) {
            if (i*prime[j]>N) break;
            pd[i*prime[j]]=1;
            if (i%prime[j]==0) {
                mu[i*prime[j]]=0;
                cnt[i*prime[j]]=cnt[i]+1;
                g[i*prime[j]]=g[i]*prime[j];
                int t=i/g[i];
                if (t==1) f[i*prime[j]]=1;
                else  f[i*prime[j]]=(cnt[t]==cnt[i*prime[j]]?-f[t]:0);
                break;
            }
            mu[i*prime[j]]=-mu[i];
            cnt[i*prime[j]]=1; g[i*prime[j]]=prime[j];
            f[i*prime[j]]=(cnt[i]==1?-f[i]:0);
        }
    }
    for (int i=1;i<=N;i++) f[i]=f[i-1]+f[i];
}
int main()
{
    freopen("a.in","r",stdin);
    init();
    scanf("%d",&T);
    while (T--) {
        scanf("%d%d",&n,&m);
        if (n>m) swap(n,m);
        int j=0; LL ans=0;
        for (int i=1;i<=n;i=j+1) {
            j=min(n/(n/i),m/(m/i));
            ans=ans+(f[j]-f[i-1])*(n/i)*(m/i);
        }
        printf("%lld\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值