题意
[egin{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)),(nleq 10^6),多次询问。
题解
考虑先直接求出所有 (F),然后就能 (O(1)) 回答所有询问。
将 (F) 差分得到 (F(n+1)-F(n)=2n+1-sum_{i=1}^nsum_{j=1}^{n}[gcd(i,j)+operatorname{lcm}(i,j)=n]),设 (G(n)=sum_{i=1}^nsum_{j=1}^{n}[gcd(i,j)+operatorname{lcm}(i,j)=n]):
[egin{aligned}
G(n)=&sum_{i=1}^nsum_{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}[iot j][d(ij+1)=n]\
=&sum_{d|n}sum_{i,j}[ij=dfrac{n}{d}-1][iot j]
end{aligned}
]
令 (t(n)=sum_{i,j}[ij=n][iot j]),只有将 (n) 的一种质因子整个分给 (i) 或 (j) 才对 (t(n)) 有贡献。故 (t(prod_{i=1}^k p_i^{q_i})(q_igeq 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
",(ans[n]+mod)%mod);
}
}