【题解】[HDU 5382] GCD?LCM【莫比乌斯反演 差分 线性筛】

题目链接

题意

\[\begin{aligned} F(n)=\sum_{i=1}^{n}\sum_{j=1}^{n}[\operatorname{lcm}(i,j)+\gcd(i,j)\geq n]\\ S(n)=\sum_{i=1}^{n}F(i) \end{aligned} \]

\(S(n)\)\(n\leq 10^6\),多次询问。

题解

考虑先直接求出所有 \(F\),然后就能 \(O(1)\) 回答所有询问。

\(F\) 差分得到 \(F(n+1)-F(n)=2n+1-\sum_{i=1}^n\sum_{j=1}^{n}[\gcd(i,j)+\operatorname{lcm}(i,j)=n]\),设 \(G(n)=\sum_{i=1}^n\sum_{j=1}^{n}[\gcd(i,j)+\operatorname{lcm}(i,j)=n]\)

\[\begin{aligned} G(n)=&\sum_{i=1}^n\sum_{j=1}^{n}[\gcd(i,j)+\operatorname{lcm}(i,j)=n]\\ =&\sum_{d=1}^{n}\sum_{i=1}^{n /d}\sum_{j=1}^{n /d}[i\bot j][d(ij+1)=n]\\ =&\sum_{d|n}\sum_{i,j}[ij=\dfrac{n}{d}-1][i\bot j] \end{aligned} \]

\(t(n)=\sum_{i,j}[ij=n][i\bot j]\),只有将 \(n\) 的一种质因子整个分给 \(i\)\(j\) 才对 \(t(n)\) 有贡献。故 \(t(\prod_{i=1}^k p_i^{q_i})(q_i\geq 1)=2^k\) 可以线性筛。\(t(n)\) 会贡献给 \(n\) 的倍数的位置,调和级数处理。之后的计算就都是 trivial 的了。

代码:

#include<bits/stdc++.h>
using namespace std;
int getint(){
    int ans=0;
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    while(c>='0'&&c<='9'){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return ans;
}
const int N=1e6+10,mod=258280327;
bool boo[N];
int pri[N],cnt=0,f[N];
int g[N],ans[N];

int main(){
    int n=1e6;
    f[1]=1;
    for(int i=2;i<=n;i++){
        if(!boo[i])pri[cnt++]=i,f[i]=2;
        for(int j=0;j<cnt&&i*pri[j]<=n;j++){
            boo[i*pri[j]]=1;
            if(i%pri[j])f[i*pri[j]]=f[i]*2;
            else{
                f[i*pri[j]]=f[i];
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j+=i+1)
            g[j]=(g[j]+f[i])%mod;
    for(int i=1;i<=n;i++)ans[i]=(ans[i-1]+2ll*i-1-g[i-1])%mod;
    for(int i=1;i<=n;i++)ans[i]=(ans[i-1]+ans[i])%mod;
    int T=getint();
    while(T--){
        int n=getint();
        printf("%d\n",(ans[n]+mod)%mod);
    }
}

posted @ 2020-12-24 23:22  破壁人五号  阅读(97)  评论(0编辑  收藏  举报