# 【BZOJ3994】【SDOI2015】约数个数和

Description

Input

Output

T行，每行一个整数，表示你所求的答案。

Sample Input

2
7 4
5 6

Sample Output

110
121

HINT
1<=N, M<=50000
1<=T<=50000

%%%ZZJ
%%%zmoiynlp

=ni=1mj=1p|iq|j[(ip,q)==1]$=\sum _{i=1} ^n \sum _{j=1} ^m \sum _{p|i} \sum _{q|j} [(\frac{i}{p},q)==1]$

=ni=1mj=1p|iq|j[(p,q)==1]$=\sum _{i=1} ^n \sum _{j=1} ^m \sum _{p|i} \sum _{q|j} [(p,q)==1]$

=np=1[np]mq=1[mq][(p,q)==1]$=\sum _{p=1} ^n [\frac{n}{p}] \sum _{q=1} ^m[\frac{m}{q}]*[(p,q)==1]$

=np=1[np]mq=1[mq]d|p,d|qμ(d)$=\sum _{p=1} ^n [\frac{n}{p}] \sum _{q=1} ^m[\frac{m}{q}]*\sum _{d|p,d|q} \mu(d)$

=min(n,m)d=1μ(d)n/dp/d=1[np]m/dq/d=1[mq]$=\sum _{d=1} ^{min(n,m)} \mu (d)\sum _{p/d=1} ^{n/d} [\frac{n}{p}] \sum _{q/d=1} ^{m/d}[\frac{m}{q}]$

=min(n,m)d=1μ(d)ndp=1[[nd]p]mdq=1[[md]q]$=\sum _{d=1} ^{min(n,m)} \mu (d)\sum _{p'=1} ^{\frac{n}{d}} [\frac{[\frac{n}{d}]}{p'}] \sum _{q'=1} ^{\frac{m}{d}} [\frac{[\frac{m}{d}]}{q'}]$

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 50005
#define to i*prime[j]
#define long long long
int t,n,m;
int prime[maxn];
int p;
int miu[maxn];//used_as_prefix_sum_later
int d[maxn];
int tmp[maxn];
void sieve()
{
miu[1]=1;
d[1]=1;
for(int i=2;i<maxn;i++)
{
if(!tmp[i])
{
miu[i]=-1;
prime[++p]=i;
d[i]=2;
tmp[i]=2;
}
for(int j=1;j<=p&&to<maxn;j++)
{
if(i%prime[j]==0)
{
tmp[to]=tmp[i]+1;
d[to]=d[i]/tmp[i]*tmp[to];
miu[to]=0;
break;
}
else
{
tmp[to]=2;
d[to]=d[i]*tmp[to];
miu[to]=-miu[i];
}
}
miu[i]+=miu[i-1];
d[i]+=d[i-1];
}
}
int main()
{
//freopen(".in","r",stdin);
sieve();
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
long ans=0;
for(int i=1,p;i<=n&&i<=m;i=p+1)
{
p=min(m/(m/i),n/(n/i));
ans+=(long)(miu[p]-miu[i-1])*d[m/i]*d[n/i];
}
printf("%lld\n",ans);
}
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120