返回顶部

AtCoder Beginner Contest 206 E - Divide Both

题目描述

求区间\([L, R]\)中, 满足:

  • \(L \le x, y \le R\)
  • \(gcd(x, y) \ne 1, \dfrac{x}{g} \ne 1, \dfrac{y}{g} \ne 1\)

\((x, y)\)数量. \((1 \le L \le R \le 10^6)\)

Solution

首先,直接求满足要求的方案不容易求,可以转化为求不满足要求的方案数
不满足要求的方案数可以分为两种:

  • \(g = 1\) :
    即求 \([L, R]\) 区间内,\(gcd(x, y) = 1\)\((x, y)\) 数量
    即: \(\sum\limits_{x = L} ^ R\sum\limits_{y = L} ^ R [gcd(x, y) = 1]\)
    带入公式: \(\sum\limits_{d | n} \mu (d) = [n = 1]\)
    得: \(\sum\limits_{x = L} ^ R\sum\limits_{y = L} ^ R\sum\limits_{d | gcd(x, y)} \mu (d)\)
    = \(\sum\limits_{d = 1} ^ R \mu (d) * \left\lfloor\dfrac{R}{d} - \dfrac{L - 1}{d}\right\rfloor * \left\lfloor\dfrac{R}{d} - \dfrac{L - 1}{d}\right\rfloor\)
  • \(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;
} 
posted @ 2021-07-03 16:32  __October  阅读(97)  评论(0编辑  收藏  举报