链接:
题目大意:
构造 (q) 个二元组 ((x_i,y_i)),每个二元组的操作是把 (a_{x_i},a_{y_i}) 的值都变为 (f(a_{x_i},a_{y_i}))。(f(x)) 意义不重要。顺序对二元组进行操作,你要使得最后 (a_i) 最多只有两个不同的数。
(1leq nleq 15000),(1leq qleq 5 imes 10^5)。
正文:
n 在 2 的整次幂:
按照样例所给的方法,很容易想到一种构造方案(假设 (n) 是 (2) 的整次幂):
粗略计算一下,如果要把 (n) 个数全合并为同一个,方案数有 (frac{nlog 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
", cnt);
for (int i = 1; i <= cnt; i++) printf ("%d %d
", a[i][0], a[i][1]);
return 0;
}