题目描述
神犇YY虐完数论后给傻×kAc出了一题
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc这种傻×必然不会了,于是向你来请教……
多组输入
输入格式
第一行一个整数T 表述数据组数
接下来T行,每行两个正整数,表示N, M
输出格式
T行,每行一个整数表示第i组数据的结果
输入输出样例
输入 #1
2
10 10
100 100
输出 #1
30
2791
说明/提示
T = 10000
N, M <= 10000000
解释:假设 n ≤ m n\le m n≤m那么
a n s = ∑ p ∈ p r i m e ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = p ] ans=\sum\limits_{p \in prime}\sum\limits_{i=1}^n\sum\limits_{j=1}^m[gcd(i,j)==p] ans=p∈prime∑i=1∑nj=1∑m[gcd(i,j)==p]
= ∑ p ∈ p r i m e ∑ i = 1 [ n p ] ∑ j = 1 [ m p ] [ g c d ( i , j ) = = 1 ] =\sum\limits_{p \in prime}\sum\limits_{i=1}^{ [\frac{n}{p}] }\sum\limits_{j=1}^{[\frac{m}{p}]}[gcd(i,j)==1] =p∈prime∑i=1∑[pn]j=1∑[pm][gcd(i,j)==1]
= ∑ p ∈ p r i m e ∑ i = 1 [ n p ] ∑ j = 1 [ m p ] ∑ k ∣ g c d ( i , j ) μ ( k ) =\sum\limits_{p \in prime}\sum\limits_{i=1}^{ [\frac{n}{p}] }\sum\limits_{j=1}^{[\frac{m}{p}]}\sum\limits_{ k|gcd(i,j) }\mu(k) =p∈prime∑i=1∑[pn]j=1∑[pm]k∣gcd(i,j)∑μ(k)
= ∑ p ∈ p r i m e ∑ k = 1 n μ ( k ) [ n k p ] [ m k p ] =\sum\limits_{p \in prime}\sum\limits_{k=1}^n\mu(k)[\frac{n}{kp}][\frac{m}{kp}] =p∈prime∑k=1∑nμ(k)[kpn][kpm]设 x = k p x=kp x=kp则
= ∑ p ∈ p r i m e ∑ k = 1 n μ ( x p ) [ n x ] [ m x ] =\sum\limits_{p \in prime}\sum\limits_{k=1}^n\mu(\frac{x}{p})[\frac{n}{x}][\frac{m}{x}] =p∈prime∑k=1∑nμ(px)[xn][xm]
= ∑ x = 1 n ∑ p ∈ p r i m e , p ∣ x μ ( x p ) [ n x ] [ m x ] =\sum\limits_{x=1}^n\sum\limits_{p \in prime, p|x }\mu(\frac{x}{p})[\frac{n}{x}][\frac{m}{x}] =x=1∑np∈prime,p∣x∑μ(px)[xn][xm]
设 f ( x ) = ∑ p ∈ p r i m e , p ∣ x μ ( x p ) f(x)=\sum\limits_{p \in prime, p|x }\mu(\frac{x}{p}) f(x)=p∈prime,p∣x∑μ(px)
a n s = ∑ x = 1 n f ( x ) [ n x ] [ m x ] ans=\sum\limits_{x=1}^nf(x)[\frac{n}{x}][\frac{m}{x}] ans=x=1∑nf(x)[xn][xm]
x = i ∗ y x=i*y x=i∗y,其中 y y y为最小质因数.
- (1) x ∈ p r i m e x \in prime x∈prime,则 f ( x ) = μ ( 1 ) = 1 f(x)=\mu(1)=1 f(x)=μ(1)=1
- (2)
i
m
o
d
y
=
0
i \mod y=0
imody=0
- i i i 没有同一个质因子出现一次以上,只有 p = y p=y p=y时不等于0, f ( x ) = μ ( i ) f(x)=\mu(i) f(x)=μ(i)
- i i i 有同一个质因子出现一次以上, f ( x ) = μ ( i ) = 0 f(x)=\mu(i)=0 f(x)=μ(i)=0
- (3)
i
m
o
d
y
≠
0
i \mod y \not= 0
imody=0,
f
(
x
)
=
−
f
(
i
)
+
μ
(
y
)
f(x)=-f(i)+\mu(y)
f(x)=−f(i)+μ(y)
然后分块搞搞就OK
#include <cstdio>
#include <algorithm>
const int N=1e7+5,lnN=15;
int n,m,tot,p[N/lnN],mu[N],f[N];
bool flg[N];
void init() {
mu[1]=flg[1]=1;
for(int i=2;i<N;++i) {
if(!flg[i]) p[++tot]=i,mu[i]=-1,f[i]=1;
for(int j=1;j<=tot&&i*p[j]<N;++j) {
int x=i*p[j];
flg[x]=1;
if(i%p[j]==0) {
f[x]=mu[i];
mu[x]=0;
break;
} else {
f[x]=-f[i]+mu[i];
mu[x]=-mu[i];
}
}
f[i]+=f[i-1];
}
}
int main() {
init();
int T;
for(scanf("%d",&T);T--;) {
scanf("%d%d",&n,&m);
long long ans=0;
if(n>m) n^=m^=n^=m;
for(int i=1,j;i<=n;i=j+1){
j=std::min(n/(n/i),m/(m/i));
ans+=1LL*(f[j]-f[i-1])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
return 0;
}