其他分享
首页 > 其他分享> > 【CodeForces 1408F】Two Different

【CodeForces 1408F】Two Different

作者:互联网

链接:

洛谷

博客园

题目大意:

构造 \(q\) 个二元组 \((x_i,y_i)\),每个二元组的操作是把 \(a_{x_i},a_{y_i}\) 的值都变为 \(f(a_{x_i},a_{y_i})\)。\(f(x)\) 意义不重要。顺序对二元组进行操作,你要使得最后 \(a_i\) 最多只有两个不同的数。

\(1\leq n\leq 15000\),\(1\leq q\leq 5\times 10^5\)。

正文:

n 在 2 的整次幂:

按照样例所给的方法,很容易想到一种构造方案(假设 \(n\) 是 \(2\) 的整次幂):

粗略计算一下,如果要把 \(n\) 个数全合并为同一个,方案数有 \(\frac{n\log n}{2}\) 个,可以过。

但是直接算有点麻烦,就可以逆向递归跑。

n 不在 2 的整次幂:

把 \(n\) 分成两个部分 \([1,2^k],[n-2^k+1,n]\) 跑,其中 \(k\) 是最大数且满足 \(2^k<n\)。

代码:

const int N = 135010;

int n, m;
int a[N][2], cnt;

void dfs (int l, int r)
{
	if (l == r) return;
	int mid = l + r >> 1;
	dfs(l, mid), dfs(mid + 1, r);
	for (int i = l; i <= mid; i ++)
		a[++cnt][0] = i, a[cnt][1] = i - l + mid + 1;
}

int main()
{
	scanf ("%d", &n);
	for (m = 1; (m << 1) < n; m <<= 1);
	dfs(1, m), dfs(n - m + 1, n);
	printf ("%d\n", cnt);
	for (int i = 1; i <= cnt; i++) printf ("%d %d\n", a[i][0], a[i][1]);
	return 0;
}

标签:Different,二元,1408F,int,CodeForces,dfs,mid,leq,整次
来源: https://www.cnblogs.com/GJY-JURUO/p/14613075.html