题目描述
求区间([L, R])中, 满足:
- (L le x, y le R)
- (gcd(x, y) e 1, dfrac{x}{g} e 1, dfrac{y}{g} e 1)
的 ((x, y))数量. ((1 le L le R le 10^6))
Solution
首先,直接求满足要求的方案不容易求,可以转化为求不满足要求的方案数
不满足要求的方案数可以分为两种:
- (g = 1) :
即求 ([L, R]) 区间内,(gcd(x, y) = 1) 的 ((x, y)) 数量
即: (sumlimits_{x = L} ^ Rsumlimits_{y = L} ^ R [gcd(x, y) = 1])
带入公式: (sumlimits_{d | n} mu (d) = [n = 1])
得: (sumlimits_{x = L} ^ Rsumlimits_{y = L} ^ Rsumlimits_{d | gcd(x, y)} mu (d))
= (sumlimits_{d = 1} ^ R mu (d) * leftlfloordfrac{R}{d} - dfrac{L - 1}{d} ight floor * leftlfloordfrac{R}{d} - dfrac{L - 1}{d} ight floor)- (g != 1) :
处理 (dfrac{x}{g} = 1;or; dfrac{y}{g} = 1) 的情况
令 (x < y) , 若符合上述情况, 即 (x | y)
枚举 (x) , 计算 (x) 的倍数个数即可.
注: (L = 1) 时, ((1, 1)) 被重复计算两次,要特殊处理.
Sample Code (C++)
int L, R;
int primes[N], cnt, mu[N];
bool st[N];
void e_prime()
{
mu[1] = 1;
for(int i = 2; i < N; ++ i)
{
if(!st[i])
{
primes[cnt ++] = i;
mu[i] = -1;
}
for(int j = 0; i * primes[j] < N; ++ j)
{
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
mu[i * primes[j]] = -mu[i];
}
}
}
int main()
{
e_prime();
IOS; cin >> L >> R;
LL res = 0;
// g = 1
for(int i = 1; i <= R; ++ i)
{
LL tmp = (R / i - (L - 1) / i);
res += mu[i] * tmp * tmp;
}
//g != 1
for(int i = max(2, L); i <= R; ++ i) res += (R / i - 1) * 2;
res = (LL)(R - L) * (R - L + 1) - res;
if(L == 1) res ++;
cout << res << endl;
return 0;
}