题目大意:让你求 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] , p ∈ p r i m e \sum_{i = 1}^n\sum_{j = 1}^m[gcd(i,j) = p],p \in prime ∑i=1n∑j=1m[gcd(i,j)=p],p∈prime
转化一下式子,枚举 p: ∑ p = 2 n ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] , p ∈ p r i m e \sum_{p = 2}^n\sum_{i = 1}^n\sum_{j = 1}^m[gcd(i,j) = p],p\in prime p=2∑ni=1∑nj=1∑m[gcd(i,j)=p],p∈prime
这个式子等价于: ∑ p = 2 n ∑ i = 1 ⌊ n p ⌋ ∑ j = 1 ⌊ m p ⌋ [ g c d ( i , j ) = 1 ] , p ∈ p r i m e \sum_{p = 2}^n\sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}[gcd(i,j) = 1],p\in prime p=2∑ni=1∑⌊pn⌋j=1∑⌊pm⌋[gcd(i,j)=1],p∈prime
根据莫比乌斯函数性质, [ g c d ( i , j ) = 1 ] [gcd(i,j) = 1] [gcd(i,j)=1]可以替换成: ∑ d ∣ g c d ( i , j ) μ ( d ) \sum_{d | gcd(i,j)}\mu(d) ∑d∣gcd(i,j)μ(d),整个式子变成: ∑ p = 2 n ∑ i = 1 ⌊ n p ⌋ ∑ j = 1 ⌊ m p ⌋ ∑ d ∣ g c d ( i , j ) μ ( d ) , p ∈ p r i m e \sum_{p = 2}^n\sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d | gcd(i,j)}\mu(d),p\in prime p=2∑ni=1∑⌊pn⌋j=1∑⌊pm⌋d∣gcd(i,j)∑μ(d),p∈prime
∑ i = 1 ⌊ n p ⌋ ∑ j = 1 ⌊ m p ⌋ ∑ d ∣ g c d ( i , j ) μ ( d ) \sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d | gcd(i,j)}\mu(d) ∑i=1⌊pn⌋∑j=1⌊pm⌋∑d∣gcd(i,j)μ(d) 这里改变一下枚举项,枚举 d: ∑ p = 2 n ∑ d = 1 ⌊ n p ⌋ μ ( d ) ∑ i = 1 ⌊ n p ∗ d ⌋ ∑ j = 1 ⌊ m p ∗ d ⌋ , p ∈ p r i m e \sum_{p = 2}^n\sum_{d = 1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)\sum_{i = 1}^{\lfloor\frac{n}{p*d}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p*d}\rfloor},p\in prime p=2∑nd=1∑⌊pn⌋μ(d)i=1∑⌊p∗dn⌋j=1∑⌊p∗dm⌋,p∈prime
这时右半边直接等于: ⌊ n p ∗ d ⌋ ∗ ⌊ m p ∗ d ⌋ \lfloor\frac{n}{p * d}\rfloor*\lfloor\frac{m}{p * d}\rfloor ⌊p∗dn⌋∗⌊p∗dm⌋,化简到这一步可以两层数论分块,单组O(n)解决,但题目有T组,复杂度还需要优化。
令 T = p ∗ d T = p * d T=p∗d: ∑ p = 2 n ∑ d = 1 ⌊ n p ⌋ μ ( d ) ∗ ⌊ n T ⌋ ∗ ⌊ m T ⌋ , p ∈ p r i m e \sum_{p = 2}^n\sum_{d = 1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)*\lfloor\frac{n}{T}\rfloor*\lfloor\frac{m}{T}\rfloor ,p\in prime p=2∑nd=1∑⌊pn⌋μ(d)∗⌊Tn⌋∗⌊Tm⌋,p∈prime
再改变枚举项,枚举T: ∑ T = 1 n ⌊ n T ⌋ ∗ ⌊ m T ⌋ ∗ ∑ p ∣ T μ ( T p ) , p ∈ p r i m e \sum_{T = 1}^n\lfloor\frac{n}{T}\rfloor*\lfloor\frac{m}{T}\rfloor*\sum_{p | T}\mu(\frac{T}{p}),p\in prime T=1∑n⌊Tn⌋∗⌊Tm⌋∗p∣T∑μ(pT),p∈prime
注意此时莫比乌斯函数部分可以预处理,令 F ( T ) = ∑ p ∣ T μ ( T p ) F(T) = \sum_{p | T}\mu(\frac{T}{p}) F(T)=∑p∣Tμ(pT),可以用埃筛在 n l o g l o g n nloglogn nloglogn时间内筛出 F F F函数,再求一下前缀和,然后数论分块即可在单组 s q r t ( n ) sqrt(n) sqrt(n)时间内完成
复杂度为 O ( T ∗ s q r t ( n ) ) O(T * sqrt(n)) O(T∗sqrt(n)),T为询问组数
代码:
(太多的long long 运算会超时)
#include
using namespace std;
const int maxn = 1e7 + 10;
const int mx = 1e7;
typedef long long ll;
int t,n,m;
bool ispri[maxn];
int pri[maxn];
int mu[maxn];
int sum[maxn];
void sieve(int n) {
mu[1] = 1;
ispri[0] = ispri[1] = true;
pri[0] = 0;
for(int i = 2; i <= n; i++) {
if(!ispri[i]) {
pri[++pri[0]] = i;
mu[i] = -1;
}
for(int j = 1; j <= pri[0] && i * pri[j] <= n; j++) {
ispri[i * pri[j]] = true;
if(i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
for(int i = 1; i <= pri[0]; i++)
for(int j = 1; j * pri[i] <= n; j++)
sum[j * pri[i]] += mu[j];
for(int i = 1; i <= n; i++)
sum[i] += sum[i - 1];
}
int main() {
scanf("%d",&t);
sieve(10000000);
while(t--) {
scanf("%d%d",&n,&m);
if(n > m) swap(n,m);
int i,j;
ll res = 0;
for(i = 1; i <= n; i = j + 1) {
j = min(n / (n / i),m / (m / i));
int p1 = n / i,p2 = m / i;
res += 1ll * p1 * p2 * (sum[j] - sum[i - 1]);
}
printf("%lld\n",res);
}
return 0;
}