# [bzoj2301]Problem b莫比乌斯反演+分块优化

$\sum\limits_{\begin{array}{*{20}{c}} {a < = x < = b}\\ {c < = y < = d} \end{array}} {\gcd (x,y) = = k}$

$F(d)$为有多少对${(x,y)}$满足 ${\gcd (x,y) = = d}$的倍数

$f(d) = \sum\limits_{\begin{array}{*{20}{c}} {1 < = x < = n}\\ {1 < = y < = m} \end{array}} {\gcd (x,y) = = d}$

$\begin{array}{l} F(d) = \frac{n}{d} * \frac{m}{d}\\ \begin{array}{*{20}{l}} {F(d) = \sum\limits_{d|x} {f(x)} \Rightarrow }\\ {f(d) = \sum\limits_{d|x} {u(\frac{x}{d})F(x)} = \sum\limits_{d|x} {u(\frac{x}{d})\left\lfloor {\frac{n}{x}} \right\rfloor } \left\lfloor {\frac{m}{x}} \right\rfloor } \end{array}\\ = \sum\limits_{d|x}^{\min (n,m)} {u(\frac{x}{d})} \left\lfloor {\frac{n}{x}} \right\rfloor \left\lfloor {\frac{m}{x}} \right\rfloor \end{array}$

$\begin{array}{*{20}{l}} {f(d) = {\sum _{\begin{array}{*{20}{c}} {1 < = x < = n}\\ {1 < = y < = m} \end{array}}}\gcd (x,y) = = d}\\ { = {\sum _{\begin{array}{*{20}{c}} {1 < = x < = n}\\ {1 < = y < = m} \end{array}}}\gcd (\frac{x}{d},\frac{y}{d}) = = 1}\\ {\begin{array}{*{20}{l}} { = {\sum _{\begin{array}{*{20}{c}} {1 < = x < = \frac{n}{d}}\\ {1 < = y < = \frac{m}{d}} \end{array}}}\gcd (x,y) = = 1}\\ { = \sum\limits_{i = 1}^{\min (\frac{n}{d},\frac{m}{d})} u (i)F(i)} \end{array}}\\ { = \sum\limits_{i = 1}^{\min (\frac{n}{d},\frac{m}{d})} u (i)\left\lfloor {\frac{n}{{di}}} \right\rfloor \left\lfloor {\frac{m}{{di}}} \right\rfloor }\\ {} \end{array}$

n/(n/i)就是满足商为n/i的i的最大值

 1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 //莫比乌斯函数线性筛法
5 const int maxn=100000+5;
6 bool vis[maxn];
7 int prime[maxn],mu[maxn],sum1[maxn];
8 void init_mu(int n){
9     int cnt=0;
10     mu[1]=1;
11     for(int i=2;i<n;i++){
12         if(!vis[i]){
13             prime[cnt++]=i;
14             mu[i]=-1;
15         }
16         for(int j=0;j<cnt&&i*prime[j]<n;j++){
17             vis[i*prime[j]]=1;
18             if(i%prime[j]==0)   {mu[i*prime[j]]=0;break;}
19             else { mu[i*prime[j]]=-mu[i];}
20         }
21     }
22     for(int i=1;i<n;i++){
23         sum1[i]=sum1[i-1]+mu[i];
24     }
25 }
27     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
28     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
29     if(k=='-')x=0-x;return x;
30 }
31 int fun(int n,int m,int k){
32     n/=k,m/=k;
33     if(n>m) swap(n,m);
34     int ans=0,pos;
35     for(int i=1;i<=n;i=pos+1){
36         pos=min(n/(n/i),m/(m/i));
37         ans+=(sum1[pos]-sum1[i-1])*(n/i)*(m/i);
38     }
39     return ans;
40 }
41 int main(){
42     int t,a,b,c,d,k;
43     init_mu(100001);
51 }