P1829 [国家集训队]Crash的数字表格 / JZPTAB

传送门

$ Ans = \sum_i^N\sum_j^Mlcm(i,j)$

因为 $lcm(x,y)=xy/gcd(x,y)$

所以 $Ans = \sum_i^N\sum_j^Mij/gcd(i,j)=\sum_i^N\sum_j^M(\ i/gcd(i,j)\ )(\ j/gcd(i,j)\ ) \cdot gcd(i,j)$

改成枚举所有可能的 $gcd(i,j)=t$,变成 $Ans=\sum_t\sum_i^{\left \lfloor \frac{N}{t} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{t} \right \rfloor}ijt[gcd(i,j)==1]$

显然莫比乌斯反演

设 $f[x]=\sum_t\sum_i^{\left \lfloor \frac{N}{t} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{t} \right \rfloor}ijt[gcd(i,j)==x]$,$F[x]=\sum_t\sum_i^{\left \lfloor \frac{N}{t} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{t} \right \rfloor}ijt[x|gcd(i,j)]$

那么 $Ans=f[1]$

那么有 $F[x]=\sum_{x|d}f[d]$,直接反演

    $f[1]=\sum_{1|d}\mu(d/1)\sum_t\sum_i^{\left \lfloor \frac{N}{t} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{t} \right \rfloor}ijt[d|gcd(i,j)]$

$=\sum_d\mu(d)\sum_t\sum_i^{\left \lfloor \frac{N}{td} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{td} \right \rfloor}ijtd^2$

枚举 $T=td$,则原式 $=\sum_d\mu(d)\sum_{d|T}\sum_i^{\left \lfloor \frac{N}{T} \right \rfloor}\sum_j^{\left \lfloor \frac{M}{T} \right \rfloor}ijTd$

$=(\sum_d\mu(d)d)(\sum_{d|T}T)(\sum_i^{\left \lfloor \frac{N}{T} \right \rfloor}i)(\sum_j^{\left \lfloor \frac{M}{T} \right \rfloor}j)$

改成先枚举 $T$ 再枚举 $d$

$=(\sum_TT)(\sum_{d|T}\mu(d)d)(\sum_i^{\left \lfloor \frac{N}{T} \right \rfloor}i)(\sum_j^{\left \lfloor \frac{M}{T} \right \rfloor}j)$

显然后面的 $(\sum_i^{\left \lfloor \frac{N}{T} \right \rfloor}i)$ 和 $(\sum_j^{\left \lfloor \frac{M}{T} \right \rfloor}j)$ 可以预处理

考虑能不能预处理 $g[T]=\sum_{d|T}\mu(d)d$

发现好像可以线性筛,考虑假设此时已经知道了 $g[x]$,且 $y=xp$,$p$ 为 $y$ 唯一一个最小的质因数

那么 $g[xp]=\sum_{d|xp}\mu(d)d=(\sum_{d|x}\mu(d)d)+(\sum_{d|x}\mu(dp)dp)$

因为 $p$ 为 $y$ 唯一一个最小的质因数,所以 $gcd(d,p)=1$ ,所以 $\mu(dp)=-\mu(d)$

则 $g[xp]=(\sum_{d|x}\mu(d)d)-(\sum_{d|x}\mu(d)dp)=(\sum_{d|x}\mu(d)d)(1-p)=(1-p)g[x]$

如果 $y=xp$,$p$ 为 $y$ 最小的一个质因数但不唯一,则根据 $g$ 的定义发现 $p$ 对 $x$ 没有贡献,所以此时 $g[xp]=g[x]$

然后直接线性筛就行了,具体看代码

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2e7+7,mo=20101009;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m,mi,pri[N],mu[N],g[N],tot;
bool not_pri[N];
ll ans;
void pre()
{
    mu[1]=1; g[1]=1;
    for(int i=2;i<=mi;i++)
    {
        if(!not_pri[i]) pri[++tot]=i,mu[i]=mo-1,g[i]=mo+1-i;
        for(int j=1;j<=tot;j++)
        {
            ll t=1ll*i*pri[j]; if(t>mi) break;
            not_pri[t]=1; if(!(i%pri[j])) { g[t]=g[i]; break; }
            mu[t]=mo-mu[i]; g[t]= 1ll*g[i]*(mo+1-pri[j])%mo;
        }
    }
}
inline int sum(int x) { return 1ll*x*(x+1)/2%mo; }
int main()
{
    n=read(),m=read();
    mi=min(n,m); pre();
    for(int _d=1;_d<=mi;_d++)
    {
        ll t=g[_d],s=1ll*sum(n/_d)*sum(m/_d)%mo;
        ans=fk(ans+ ((t*s%mo)*_d%mo) );
    }
    printf("%lld\n",(ans%mo+mo)%mo);
    return 0;
}

 

posted @ 2019-07-05 15:13  LLTYYC  阅读(226)  评论(0编辑  收藏  举报