P2522 [HAOI2011]Problem b

题意:

给定 P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演,求 P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_02,P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_03P2522 [HAOI2011]Problem b(莫比乌斯反演)_i++_04 为质数的 P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_05有多少对。

分析:

莫比乌斯反演soul time:
首先说下莫比乌斯函数:
P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_06
两种情况:

  • 如果存在P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_07那么 mu[x]=0;
  • 否则等于P2522 [HAOI2011]Problem b(莫比乌斯反演)_i++_08

莫比乌斯反演 有两个形式

  • P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_09P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_10
  • 另一种形式常用P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_11P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_12

说完这些:我们看题目中的P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_13P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_14
P2522 [HAOI2011]Problem b(莫比乌斯反演)_i++_15

P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_16

我们通过上面那个莫比乌斯反演得:
通过P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_13这个式子我们可以看出他其实等于⌊ P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_18 ⌋也就是a中n的倍数乘以b中n的倍数。
符合条件:P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_19
那么:P2522 [HAOI2011]Problem b(莫比乌斯反演)_i++_20
这样f(n)就比较好求了。然后我们在将其转化令P2522 [HAOI2011]Problem b(莫比乌斯反演)_莫比乌斯反演_21 取值范围是P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_22
然后替换成P2522 [HAOI2011]Problem b(莫比乌斯反演)_i++_23
P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_24
P2522 [HAOI2011]Problem b(莫比乌斯反演)_取值范围_25

bool isprime[maxn];
ll prime[maxn], mu[maxn], cnt;

void get_mo() {
mu[1] = 1;
for(int i = 2; i < maxn; i++) {
if(!isprime[i]) {
prime[++cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt && i * prime[j] < maxn; j++) {
isprime[i * prime[j]] = 1;
if(i % prime[j]) {
mu[i * prime[j]] = -mu[i];
} else {
mu[i * prime[j]] = 0;
break;
}
}
}
for(int i = 1; i < maxn; i++) {
mu[i] += mu[i - 1];
}
}
ll solve(ll a, ll b, ll d) {
ll sum = 0;
a = a / d, b = b / d;
ll minn = min(a, b);
for(ll l = 1, r; l <= minn; l = r + 1) {
r = min(a / (a / l), b / (b / l));
sum += (mu[r] - mu[l - 1]) * (a / l) * (b / l);
}
return sum;
}
int main() {
int t;
get_mo();
cin >> t;
while(t--) {
ll a, b, d, e, c;
sf("%lld%lld%lld%lld%lld", &a, &b, &c, &e, &d);

pf("%lld\n", solve(b, e, d) - solve(a - 1, e, d) - solve(b, c - 1, d) + solve(a - 1, c - 1, d));
}
return 0;
}