题目描述
传送门
题目大意:
定义
f(n)
表示n所含质因子的最大幂指数。
求
∑i=1n∑j=1mf(gcd(i,j))
题解
设n<=m
∑k=1nf(k)∑i=1n∑j=1n[gcd(i,j)=k]
∑k=1nf(k)∑d=1nμ(d)⌊nk∗d⌋⌊nk∗d⌋
中间具体的化简过程可以参照 bzoj 4407
设 T=k∗d
∑T=1n⌊nT⌋⌊nT⌋∑d|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);
}
}