题意
企鹅国数学家 QQ 潜心研究数论,终于发现了一个简单的数论问题!
一个 QQ 数定义为一个拥有一个大于 $1$ 的完全平方数为因子的数字,一个数字的 QQ 值定义为这个数是 QQ 数的因数个数。
现在 QQ 想知道在 $[L,R]$ 范围内,每个整数的 QQ 值之和是多少?
你只需要告诉他这个数字,他就可以给你宝贵的 $10$ 分作为一个奖励!
$1 leq Lleq R leq 10^9$;
题解
很妙的莫比乌斯好题
题意为 $sum_{i=1}^n sum_{d|i} 1-mu^2(d)$
考虑化简式子哈(除法都为向下取整
$sum_{d=1}^n(1-mu^2(d)) imes frac{n}{d}$
$sum_{d=1}^n frac{n}{d}-sum_{d=1}^n mu^2(d) imes frac{n}{d}$
当 $d∈[l,r]$ 时, $frac{n}{d}=k$
考虑被减的式子
$sum k sum_{d=l}^rmu^2(d)$
$sum k(sum_{d=1}^rmu^2(d)-sum_{d=1}^{l-1}mu^2(d))$
考虑对 $sum_{d=1}^nmu^2(d)$ 进行化简,可以发现这个式子的意义就是求 $leq n$ 的不含完全平方因子的数的个数
$n-frac{n}{2^2}-frac{n}{3^2}-frac{n}{5^2}+frac{n}{6^2}...$
$sum_{i=1}^{i imes i leq n}mu(i) imes frac{n}{i^2}$
因此就预处理出 $sqrt(1e9)$ 以内的 $mu(i)$ 的前缀和,然后两重数论分块即可
#include <bits/stdc++.h> #define LL long long using namespace std; const int N=1e5+5;bool F[N]; LL L,R,mu[N],sm[N],p[N]; LL W(LL n){ LL A=0;for (LL j,i=1;i*i<=n;i=j+1) j=sqrt(n/(n/(i*i))), A+=(sm[j]-sm[i-1])*(n/(i*i)); return A; } LL D(LL n){ LL A=0;for (LL r,l=1;l<=n;l=r+1) r=n/(n/l),A+=(n/l)*(r-l+1-W(r)+W(l-1)); return A; } int main(){ mu[1]=sm[1]=1; for (int i=2;i<=N-5;i++){ if (!F[i]) p[++p[0]]=i,mu[i]=-1; for (int j=1;j<=p[0] && p[j]*i<=N-5;j++){ F[p[j]*i]=1; if (i%p[j]==0) break; else mu[p[j]*i]=-mu[i]; } sm[i]=sm[i-1]+mu[i]; } scanf("%lld%lld",&L,&R); return printf("%lld ",D(R)-D(L-1)),0; }