题目:BZOJ2820.
题目大意:求有多少对 x , y x,y x,y满足 1 ≤ x ≤ n , 1 ≤ y ≤ m 1\leq x \leq n,1\leq y \leq m 1≤x≤n,1≤y≤m且 g c d ( x , y ) gcd(x,y) gcd(x,y)为质数.
1 ≤ n , m ≤ 1 0 7 1\leq n,m\leq 10^7 1≤n,m≤107,数据组数 = 1 0 4 =10^4 =104.
设素数集为P,那么题目要求即为:
∑ p ∈ P ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] \sum_{p\in P}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p] p∈P∑i=1∑nj=1∑m[gcd(i,j)=p]
钦定 n ≤ m n\leq m n≤m,设 a = ⌊ n p ⌋ , b = ⌊ m p ⌋ a=\left \lfloor \frac{n}{p} \right \rfloor,b=\left \lfloor \frac{m}{p} \right \rfloor a=⌊pn⌋,b=⌊pm⌋,那么:
∑ p ∈ P ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] = ∑ p ∈ P ∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = 1 ] = ∑ p ∈ P ∑ i = 1 a ∑ j = 1 b ∑ d ∣ i ∧ d ∣ j μ ( d ) = ∑ d = 1 ⌊ n p ⌋ ∑ p ∈ P μ ( d ) ⌊ n p d ⌋ ⌊ m p d ⌋ \sum_{p\in P}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p]\\ =\sum_{p\in P}\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)=1]\\ =\sum_{p\in P}\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{d|i\wedge d|j}\mu(d)\\ =\sum_{d=1}^{\left\lfloor\frac{n}{p}\right\rfloor}\sum_{p\in P} \mu(d)\left\lfloor\frac{n}{pd} \right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor\\ p∈P∑i=1∑nj=1∑m[gcd(i,j)=p]=p∈P∑i=1∑aj=1∑b[gcd(i,j)=1]=p∈P∑i=1∑aj=1∑bd∣i∧d∣j∑μ(d)=d=1∑⌊pn⌋p∈P∑μ(d)⌊pdn⌋⌊pdm⌋
设 k = p d k=pd k=pd,那么:
∑ p ∈ P ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] = ∑ k = 1 n ∑ p ∈ P ∧ p ∣ k μ ( k p ) ⌊ n k ⌋ ⌊ m k ⌋ \sum_{p\in P}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p]\\ =\sum_{k=1}^{n}\sum_{p\in P\wedge p|k}\mu(\frac{k}{p})\left\lfloor\frac{n}{k} \right\rfloor\left\lfloor\frac{m}{k}\right\rfloor p∈P∑i=1∑nj=1∑m[gcd(i,j)=p]=k=1∑np∈P∧p∣k∑μ(pk)⌊kn⌋⌊km⌋
设一个函数: f ( k ) = ∑ p ∈ P ∧ p ∣ k μ ( k p ) f(k)=\sum_{p\in P\wedge p|k}\mu(\frac{k}{p}) f(k)=∑p∈P∧p∣kμ(pk),那么:
∑ p ∈ P ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] = ∑ k = 1 n f ( k ) ⌊ n k ⌋ ⌊ m k ⌋ \sum_{p\in P}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p]=\sum_{k=1}^{n}f(k)\left\lfloor\frac{n}{k} \right\rfloor\left\lfloor\frac{m}{k}\right\rfloor p∈P∑i=1∑nj=1∑m[gcd(i,j)=p]=k=1∑nf(k)⌊kn⌋⌊km⌋
发现这个式子中,只要 f f f函数能够用线性筛筛出即可用除法分块做到 O ( n + m ) O(\sqrt{n}+\sqrt{m}) O(n+m)求解,所以尝试推导这个函数在线性筛三种情况下的值:
1.当 i i i为质数时,显然 f ( i ) = 1 f(i)=1 f(i)=1.
2.当 g c d ( i , p r [ j ] ) = 1 gcd(i,pr[j])=1 gcd(i,pr[j])=1时,可以推导:
KaTeX parse error: Expected '}', got '\wdge' at position 27: …\\=\sum_{p\in P\̲w̲d̲g̲e̲ ̲p|(i*pr[j])}\mu…
3.当 p r [ j ] ∣ i pr[j]|i pr[j]∣i时,可以推导:
f ( i ∗ p r [ j ] ) = ∑ p ∈ P ∧ p ∣ ( i ∗ p r [ j ] ) μ ( i ∗ p r [ j ] p ) = μ ( i ∗ p r [ j ] p r [ j ] ) + ∑ p ∈ P ∧ p ∣ i μ ( i ∗ p r [ j ] p ) = μ ( i ) f(i*pr[j])\\ =\sum_{p\in P\wedge p|(i*pr[j])}\mu(\frac{i*pr[j]}{p})\\ =\mu(\frac{i*pr[j]}{pr[j]})+\sum_{p\in P\wedge p|i}\mu(\frac{i*pr[j]}{p})\\ =\mu(i) f(i∗pr[j])=p∈P∧p∣(i∗pr[j])∑μ(pi∗pr[j])=μ(pr[j]i∗pr[j])+p∈P∧p∣i∑μ(pi∗pr[j])=μ(i)
发现我们就这么把 f f f函数筛出来了,所以除法分块一下就可以了,时间复杂度 O ( m + T m ) O(m+T\sqrt m) O(m+Tm).
代码如下:
#include
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=10000000;
int n,m;
int pr[N+9],tp,b[N+9];
LL mu[N+9],f[N+9];
void sieve(int n){
for (int i=2;i<=n;++i) b[i]=1;
mu[1]=1;
for (int i=2;i<=n;++i){
if (b[i]) pr[++tp]=i,mu[i]=-1,f[i]=1;
for (int j=1;j<=tp&&pr[j]*i<=n;++j){
b[i*pr[j]]=0;
if (i%pr[j]==0){
mu[i*pr[j]]=0;
f[i*pr[j]]=mu[i];
break;
}
mu[i*pr[j]]=-mu[i];
f[i*pr[j]]=mu[i]-f[i];
}
}
for (int i=1;i<=n;++i)
f[i]+=f[i-1];
}
LL Query(int n,int m){
if (n>m) swap(n,m);
LL ans=0;
for (int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(f[r]-f[l-1])*(n/l)*(m/l);
}
return ans;
}
Abigail start(){
sieve(N);
}
Abigail into(){
scanf("%d%d",&n,&m);
}
Abigail outo(){
printf("%lld\n",Query(n,m));
}
int main(){
start();
int T;
scanf("%d",&T);
while (T--){
into();
outo();
}
return 0;
}