Label
利用Möbius函数改写容斥式经典题
Description
给定
Q
Q
Q组询问,每组询问给定三个正整数
a
,
b
,
d
(
Q
,
a
,
b
,
d
≤
5
×
1
0
4
)
a,b,d(Q,a,b,d\leq5\times 10^4)
a,b,d(Q,a,b,d≤5×104),求
∑
i
=
1
a
∑
j
=
1
b
[
g
c
d
(
i
,
j
)
=
=
d
]
\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d]
i=1∑aj=1∑b[gcd(i,j)==d]
Solution
这个题显然可以用反演做,推出来的式子和利用容斥推得的式子基本一样。此处只讲容斥做法。
在luoguP1447里,我们曾利用 f n = ⌊ a d ⌋ ⌊ b d ⌋ − ∑ i = 2 i d ≤ m i n ( a , b ) f i d f_n=\lfloor \frac{a}{d} \rfloor\lfloor \frac{b}{d} \rfloor-\sum_{i=2}^{id\leq min(a,b)}f_{id} fn=⌊da⌋⌊db⌋−∑i=2id≤min(a,b)fid来 O ( n l o g n ) O(nlogn) O(nlogn)求 f 1 ∼ f n f_1\sim f_n f1∼fn ( f k = ∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = = k ] ) (f_k=\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==k]) (fk=∑i=1a∑j=1b[gcd(i,j)==k]),但对于此题,由于 a , b a,b a,b是变化的,故若想以与P1447相同的容斥思路来解此题,那么对于每一次询问,我们都需要重新求一遍 f 1 ∼ f n f_1\sim f_n f1∼fn,这样一来算法总复杂度 O ( n 2 l o g n ) O(n^2logn) O(n2logn),不可取,故考虑更优的容斥方法。
之前的容斥方法是将最大公约数为 k d kd kd的数的集合从被 d d d整除的数的集合中剔除掉从而得到 f d f_d fd,故此处我们考虑将原条件变形以尝试得到新的限制(约束)条件。
由于常规套路:
g
c
d
(
i
,
j
)
=
d
↔
g
c
d
(
i
d
,
j
d
)
=
1
gcd(i,j)=d\leftrightarrow gcd(\frac{i}{d},\frac{j}{d})=1
gcd(i,j)=d↔gcd(di,dj)=1,故首先:
∑
i
=
1
a
∑
j
=
1
b
[
g
c
d
(
i
,
j
)
=
=
d
]
↔
∑
i
=
1
⌊
a
d
⌋
∑
j
=
1
⌊
b
d
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d]\leftrightarrow \sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[gcd(i,j)==1]
i=1∑aj=1∑b[gcd(i,j)==d]↔i=1∑⌊da⌋j=1∑⌊db⌋[gcd(i,j)==1]
根据经典的容斥思路 ∣ ⋂ i = 1 n S i ∣ = ∣ U ∣ − ∣ ⋃ i = 1 n ∁ U S i ∣ |\bigcap_{i=1}^{n}S_i|=|U|-|\bigcup_{i=1}^{n}\complement_US_{i}| ∣i=1⋂nSi∣=∣U∣−∣i=1⋃n∁USi∣,考虑满足互质的有序二元组所满足的限制,其即为: ∀ ( x , y ) ∀ p ∈ p r i m e , p ∤ x ∧ p ∤ y \forall(x,y)\forall p\in prime,p\nmid x\wedge p\nmid y ∀(x,y)∀p∈prime,p∤x∧p∤y。
那么,令 ∁ U S i = { x ∣ p i ∣ x } \complement_US_{i}=\{x|p_i|x\} ∁USi={x∣pi∣x},且多个 ∁ U S i \complement_US_{i} ∁USi的交= { x ∣ ∏ p i ∣ x } \{x|\prod p_i|x\} {x∣∏pi∣x};又由于根据Möbius函数的定义,含有奇数个质因子时值为-1,偶数个质因子时值为 1 1 1,而根据此处容斥式的定义, ∏ p i \prod p_i ∏pi内含有 p i p_i pi的个数奇偶性正好对应了容斥式内的正负;而且根据 S i S_i Si定义,含有多个相同奇因子的 i i i对应集合不予考虑,所以,我们可以利用这一点写出此题的容斥式:
设 D ( d ) = ∑ i = 1 ⌊ a d ⌋ ∑ j = 1 ⌊ b d ⌋ [ p ∣ i ∧ p ∣ j ] D(d)=\sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[p\mid i\wedge p\mid j] D(d)=∑i=1⌊da⌋∑j=1⌊db⌋[p∣i∧p∣j],故:
∑ i = 1 ⌊ a d ⌋ ∑ j = 1 ⌊ b d ⌋ [ g c d ( i , j ) = = 1 ] = ∑ i = 1 m i n ( ⌊ a d ⌋ , ⌊ b d ⌋ ) μ ( i ) D ( i ) = = ∑ i = 1 m i n ( ⌊ a d ⌋ , ⌊ b d ⌋ ) μ ( i ) ⌊ a d i ⌋ ⌊ b d i ⌋ \sum_{i=1}^{\lfloor \frac{a}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{b}{d} \rfloor}[gcd(i,j)==1]=\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)D(i)==\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)\lfloor \frac{a}{di} \rfloor\lfloor \frac{b}{di} \rfloor ∑i=1⌊da⌋∑j=1⌊db⌋[gcd(i,j)==1]=∑i=1min(⌊da⌋,⌊db⌋)μ(i)D(i)==∑i=1min(⌊da⌋,⌊db⌋)μ(i)⌊dia⌋⌊dib⌋
所以
a
n
s
=
∑
i
=
1
m
i
n
(
⌊
a
d
⌋
,
⌊
b
d
⌋
)
μ
(
i
)
⌊
a
d
i
⌋
⌊
b
d
i
⌋
ans=\sum_{i=1}^{min(\lfloor \frac{a}{d} \rfloor,\lfloor \frac{b}{d} \rfloor)}\mu(i)\lfloor \frac{a}{di} \rfloor\lfloor \frac{b}{di} \rfloor
ans=i=1∑min(⌊da⌋,⌊db⌋)μ(i)⌊dia⌋⌊dib⌋
根据前面所讲的数论分块,上面这个式子可分块求,注意预处理 μ ( i ) \mu(i) μ(i)前缀和。
算法时间复杂度: O ( n n ) O(n\sqrt n) O(nn)
Code
#include<cstdio>
#include<iostream>
#define ri register int
#define ll long long
using namespace std;
const int MAXN=5e4;
int Q,cnt;
ll a,b,d,miu[MAXN+20],prime[MAXN+20],sum[MAXN+20],ans;
bool notprime[MAXN+20];
void Mobius()//利用线性筛O(n)求Mobius函数
{
miu[1]=1,notprime[1]=true;
for(ri i=2;i<=MAXN;++i)
{
if(!notprime[i]) prime[++cnt]=i,miu[i]=-1;
for(ri j=1;j<=cnt&&i*prime[j]<=MAXN;++j)
{
notprime[i*prime[j]]=true;
if(i%prime[j]==0) break;
else miu[i*prime[j]]=-miu[i];
}
}
for(ri i=1;i<=MAXN;++i) sum[i]=sum[i-1]+miu[i];
}
int main()
{
std::ios::sync_with_stdio(false);
Mobius();
cin>>Q;
for(ri op=1;op<=Q;++op)
{
cin>>a>>b>>d;
a/=d,b/=d;
ans=0LL;
ll l=1,r,sj=min(a,b);
while(l<=sj)
{
r=min(a/(a/l),b/(b/l));
ans+=(sum[r]-sum[l-1])*(a/l)*(b/l);
l=r+1;
}
cout<<ans<<'\n';
}
return 0;
}