https://www.luogu.org/problem/P3455
题意:求满足x<=a,y<=b,gcd(x,y)=d的x,y对数。
分析:莫比乌斯反演和除法分块。
egin{split}
sum_{i=1}^{a}sum_{j=1}^{b}[gcd(i,j)=d]
ewline
sum_{i=1}^{a/d}sum_{j=1}^{b/d}[gcd(i,j)=1]
ewline
sum_{i=1}^{a/d}sum_{j=1}^{b/d}sum_{k|gcd(i,j)}^{ }mu(k)
ewline
sum_{k=1}^{min(a/d,b/d)}mu(k)sum_{i=1}^{a/d}[k|i]sum_{j=1}^{b/d}[k|j]
ewline
a'=a/d , b'=b/d
ewline
sum_{k=1}^{min(a',b')}mu(k)[frac{a'}{k}][frac{b'}{k}]
end{split}
此时为n,可以再分块成$sqrt{n}$。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 5e4+10; 4 int mu[maxn],prime[maxn],cnt=0; 5 bool vis[maxn]; 6 7 inline void init(){ 8 mu[1] = 1; 9 for(int i=2;i<maxn;i++){ 10 if (vis[i] ==false){ 11 prime[cnt++] = i; 12 mu[i] = -1; 13 } 14 for(int j=0;j<cnt&&prime[j]*i<maxn;j++){ 15 vis[i*prime[j]] = true; 16 if(i%prime[j]==0) {mu[i*prime[j]] = 0;break;} 17 else mu[i*prime[j]] = -mu[i]; 18 } 19 } 20 for(int i=2;i<maxn;i++) 21 mu[i] += mu[i-1]; 22 } 23 24 inline int solve(int a,int b){ 25 int ans = 0; 26 if(a>b) swap(a,b); 27 for(int l=1,r;l<=a;l=r+1){ 28 r = min(a/(a/l),b/(b/l)); 29 ans += (mu[r]-mu[l-1])*(a/l)*(b/l); 30 } 31 return ans; 32 } 33 34 int main(){ 35 init(); 36 int t,a,b,d; 37 cin>>t; 38 while(t--){ 39 cin>>a>>b>>d; 40 cout<<solve(a/d,b/d)<<endl; 41 } 42 return 0; 43 }