[HAOI2011] Problem B
Statement
A n s = ∑ i = a b ∑ j = c d [ gcd ( i , j ) = k ] Ans=\sum_{i=a}^b\sum_{j=c}^d[\gcd(i,j)=k] Ans=∑i=ab∑j=cd[gcd(i,j)=k]
Solution
设: s ( a , b , c , d , k ) = ∑ i = a b ∑ j = b c [ gcd ( i , j ) = k ] s(a,b,c,d,k)=\sum_{i=a}^b\sum_{j=b}^c[\gcd(i,j)=k] s(a,b,c,d,k)=∑i=ab∑j=bc[gcd(i,j)=k]
考虑容斥可得 A n s = s ( a , b , c , d , k ) = s ( 1 , b , 1 , d ) − s ( 1 , b , 1 , c − 1 , k ) − s ( 1 , a − 1 , 1 , d , k ) + s ( 1 , a − 1 , 1 , c − 1 , k ) Ans=s(a,b,c,d,k)=s(1,b,1,d)-s(1,b,1,c-1,k)-s(1,a-1,1,d,k)+s(1,a-1,1,c-1,k) Ans=s(a,b,c,d,k)=s(1,b,1,d)−s(1,b,1,c−1,k)−s(1,a−1,1,d,k)+s(1,a−1,1,c−1,k).
我们考虑一个子问题 s ( 1 , i , 1 , j , k ) = ∑ i = 1 N ∑ j = 1 M [ gcd ( i , j ) = k ] s(1,i,1,j,k)=\sum_{i=1}^N\sum_{j=1}^M[\gcd(i,j)=k] s(1,i,1,j,k)=∑i=1N∑j=1M[gcd(i,j)=k].
式子化简后和YY的GCD式子是一致的.
设: f ( d ) = ∑ i = 1 N ∑ j = 1 M [ gcd ( i , j ) = d ] f(d)=\sum_{i=1}^N\sum_{j=1}^M[\gcd(i,j)=d] f(d)=∑i=1N∑j=1M[gcd(i,j)=d].
设: g ( d ) = ∑ d ∣ d ′ f ( d ′ ) = ∑ i = 1 N ∑ j = 1 M [ d ∣ i ] [ d ∣ j ] = ∑ i = 1 N [ d ∣ i ] ∑ i = 1 M [ d ∣ j ] = ∑ i = 1 N [ d ∣ i ] ⌊ M d ⌋ = ⌊ N d ⌋ ⋅ ⌊ M d ⌋ g(d)=\sum_{d|d'}f(d')=\sum_{i=1}^N\sum_{j=1}^M[d|i][d|j]=\sum_{i=1}^N[d|i]\sum_{i=1}^M[d|j]=\sum_{i=1}^N[d|i]\lfloor\frac{M}{d}\rfloor=\lfloor\frac{N}{d}\rfloor\cdot\lfloor\frac{M}{d}\rfloor g(d)=∑d∣d′f(d′)=∑i=1N∑j=1M[d∣i][d∣j]=∑i=1N[d∣i]∑i=1M[d∣j]=∑i=1N[d∣i]⌊dM⌋=⌊dN⌋⋅⌊dM⌋.
则: f ( d ) = ∑ d ∣ d ′ μ ( d ′ d ) g ( d ′ ) f(d)=\sum_{d|d'}\mu(\frac{d'}{d})g(d') f(d)=∑d∣d′μ(dd′)g(d′).
由 A n s = ∑ p ∈ p r i m e ∑ i = 1 N ∑ j = 1 N [ gcd ( i , j ) = p ] Ans=\sum_{p\in prime}\sum_{i=1}^N\sum_{j=1}^N[\gcd(i,j)=p] Ans=∑p∈prime∑i=1N∑j=1N[gcd(i,j)=p].
可得:
A
n
s
=
∑
p
∈
p
r
i
m
e
f
(
p
)
Ans=\sum_{p\in prime}f(p)
Ans=∑p∈primef(p).
A
n
s
=
∑
p
∈
p
r
i
m
e
∑
i
=
1
N
∑
j
=
1
N
[
gcd
(
i
,
j
)
=
p
]
=
∑
p
∈
p
r
i
m
e
f
(
p
)
=
∑
p
∈
p
r
i
m
e
∑
p
∣
d
min
{
N
,
M
}
μ
(
d
p
)
⌊
N
d
⌋
⌊
M
d
⌋
=
∑
d
=
1
min
{
N
,
M
}
∑
p
∣
d
且
p
∈
p
r
i
m
e
μ
(
d
p
)
⌊
N
d
⌋
⌊
M
d
⌋
=
∑
d
=
1
min
{
N
,
M
}
⌊
N
d
⌋
⌊
M
d
⌋
∑
p
∣
d
且
p
∈
p
r
i
e
m
μ
(
d
p
)
\begin{aligned}Ans&=\sum_{p\in prime}\sum_{i=1}^N\sum_{j=1}^N[\gcd(i,j)=p]\\ &=\sum_{p\in prime}f(p)\\ &=\sum_{p\in prime}\sum_{p|d}^{\min\{N,M\}}\mu(\frac{d}{p})\lfloor\frac{N}{d}\rfloor\lfloor\frac{M}{d}\rfloor\\ &=\sum_{d=1}^{\min\{N,M\}}\sum_{p|d且p\in prime}\mu(\frac{d}{p})\lfloor\frac{N}{d}\rfloor\lfloor\frac{M}{d}\rfloor\\ &=\sum_{d=1}^{\min\{N,M\}}\lfloor\frac{N}{d}\rfloor\lfloor\frac{M}{d}\rfloor\sum_{p|d且p\in priem}\mu(\frac{d}{p}) \end{aligned}
Ans=p∈prime∑i=1∑Nj=1∑N[gcd(i,j)=p]=p∈prime∑f(p)=p∈prime∑p∣d∑min{N,M}μ(pd)⌊dN⌋⌊dM⌋=d=1∑min{N,M}p∣d且p∈prime∑μ(pd)⌊dN⌋⌊dM⌋=d=1∑min{N,M}⌊dN⌋⌊dM⌋p∣d且p∈priem∑μ(pd)
我们发现
∑
p
∣
d
且
p
∈
p
r
i
m
e
μ
(
d
p
)
\sum\limits_{p|d且 p\in prime}\mu(\frac{d}{p})
p∣d且p∈prime∑μ(pd)是可以预处理的, 该部分我们枚举
p
∈
p
r
i
m
e
p\in prime
p∈prime即可, 时间复杂度是
O
(
n
log
log
n
)
O(n\log\log n)
O(nloglogn)的和
Eratosthenes
\text{Eratosthenes}
Eratosthenes筛法(埃拉托特尼筛法, 简称埃氏筛法)该部分时间复杂度和写法相似.
然后一次询问我们只需要用数论分块就可以将复杂度做到 O ( N log log N + T N ) O(N\log\log N+T\sqrt N) O(NloglogN+TN).
Code
# include "iostream"
# include "cstdio"
using namespace std;
const int maxm=5e4+10;
int Mu[maxm],Prime[maxm],Cnt;
bool Visit[maxm];
void Init(int N){
Mu[1]=1;
register int i,j;
for(i=2;i<=N;i++){
if(!Visit[i]){
Prime[++Cnt]=i;
Mu[i]=-1;
}
for(j=1;j<=Cnt && Prime[j]*i<=N;j++){
Visit[i*Prime[j]]=1;
if(i%Prime[j]==0){Mu[Prime[j]*i]=0;break;}
Mu[i*Prime[j]]=-Mu[i];
}
}
for(i=2;i<=N;i++) Mu[i]+=Mu[i-1];
return;
}
int Solve(int N,int M,int K){
N/=K;M/=K;
register int i,j,Ans=0;
if(N>M) swap(N,M);
for(i=1;i<=N;i=j+1){
j=min(N/(N/i),M/(M/i));
Ans+=(N/i)*(M/i)*(Mu[j]-Mu[i-1]);
}
return Ans;
}
int main(){
register int T;
int A,B,C,D,K;
scanf("%d",&T);
Init(5e4);
while(T--){
scanf("%d%d%d%d%d",&A,&B,&C,&D,&K);
printf("%d\n",Solve(B,D,K)-Solve(B,C-1,K)-Solve(A-1,D,K)+Solve(A-1,C-1,K));
}
return 0;
}