BZOJ1101——莫比乌斯函数&&入门
题目
有$50000$次查询,对于给定的整数$a,b$和$d$,有多少正整数对$x$和$y$,满足$x \leq a$,$y \leq b$,并且$gcd(x, y)=d$。$1 \leq k \leq a,b \leq 50000$.
分析
求有多少对$(x,y)$满足$x \leq a$,$y \leq b$,并且 $gcd(x, y)=d$,等价于求有多少对$(x, y)$满足$x \leq \frac{a}{d}, y \leq \frac{b}{d}$并且$x, y$互质.
设$D(a, b, d)$表示满足$x \leq a, y \leq b$且$d | gcd(x, y)$的二元组的对数。显然只要$x, y$都是$d$的倍数即可。$1 \sim a$之间$d$的倍数有$\left \lfloor \frac{a}{d} \right \rfloor$个。故$D(a, b, d) = \left \lfloor \frac{a}{d} \right \rfloor \left \lfloor \frac{b}{d} \right \rfloor$.
设$F(a, b)$ 表示满足$x \leq a$,$y \leq b$ 且 $x, y$互质的二元组的对数。根据容斥原理:
$$F(a,b)=\sum_{i=1}^{min(a,b)} \mu(i)*D(a,b,i)$$
上式的意思是,没有任何限制的二元组总数为 $D(a, b, 1)=a*b$,应该减去$gcd(a, b)$是$2,3,5 \cdots$的倍数的二元组数量,这样又重复减掉了$gcd(a, b)$既是$2$的倍数、又是$3$的倍数的二元组数量,应该加回来。依此类推,$D(a, b, i)$的系数恰好就是莫比乌斯函数.
由整除分块的知识,我们知道:$\forall i \in [x, min(\left \lfloor a/ \left \lfloor a/x \right \rfloor \right \rfloor), \left \lfloor b/\left \lfloor b/x \right \rfloor \right \rfloor]$,$D(a,b,i)=\left \lfloor a/i \right \rfloor\left \lfloor b/i \right \rfloor$ 的值都是相等的,预处理出莫比乌斯函数的前缀和,即可直接累加这一段的答案。这样的段只有$O(2\sqrt{min(a,b)})$个.
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 50000 + 10; 5 int miu[maxn],vis[maxn], smiu[maxn]; 6 7 void getmiu(int n) 8 { 9 for(int i=1;i <= n;i++) miu[i]=1, vis[i]; 10 for(int i=2;i <= n;i++) 11 { 12 if(vis[i]) continue; 13 miu[i] = -1; //i没有被访问,说明i是素数 14 for(int j = 2*i; j <= n;j += i) 15 { 16 vis[j] = 1; 17 if(j % (i*i) == 0) miu[j] = 0; //含有平方因子 18 else miu[j] *= -1; 19 } 20 } 21 22 for(int i = 1;i <= n;i++) smiu[i] = smiu[i-1] + miu[i]; 23 } 24 25 int f(int a, int b) 26 { 27 int ans = 0; 28 for(int l=1, r; l <= min(a, b);l = r+1) 29 { 30 r = min(a / (a / l), b / (b / l)); 31 ans += (smiu[r] - smiu[l-1]) * (a/l) * (b/l); //按段累加 32 //printf("%d %d\n", l, r); 33 } 34 printf("%d\n", ans); 35 } 36 37 int main() 38 { 39 int T; 40 scanf("%d", &T); 41 getmiu(maxn); 42 //for(int i=1; i <= 20;i++) printf("%d\n", miu[i]); 43 while(T--) 44 { 45 int a, b, k; 46 scanf("%d%d%d", &a, &b, &k); 47 f(a/k, b/k); 48 } 49 return 0; 50 }