【YbtOJ#20068】连通子图

题目

题目链接:http://noip.ybtoj.com.cn/contest/102/problem/2

输入保证答案一定存在,你输出的 \(n\) 必须是正整数且不得超过 60。对每个询问,你只需要输出任意一个合法解即可。

思路

考虑已知的一个以 \(x\) 为根的有 \(k\) 个与 \(x\) 连接的连通块,此时如果我们给 \(x\) 加一个儿子,那么连通块数量变成 \(2k\);如果加上一个父亲 \(y\),那么以 \(y\) 为根的连通块就有 \(k+1\) 个。
那么任意一个数 \(x\) 都可以通过 \(2\log x\) 次操作得出,所以最多需要使用 \(2\log(10^9)\leq 60\) 次操作。
时间复杂度 \(O(T\log n)\)

代码

#include <bits/stdc++.h>
using namespace std;

const int N=65;
int n,m,tot,ans[N][2];

void dfs(int k,int rt)
{
	if (k==1) return;
	ans[++m][0]=rt; ans[m][1]=++tot;
	if (k&1) dfs(k-1,tot);
		else dfs(k/2,rt);
}

int main()
{
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	while (scanf("%d",&n)!=EOF)
	{
		m=0; tot=1;
		dfs(n,1);
		printf("%d\n",m+1);
		for (int i=1;i<=m;i++)
			printf("%d %d\n",ans[i][0],ans[i][1]);
	}
	return 0;
}
posted @ 2020-10-19 18:57  stoorz  阅读(180)  评论(0)    收藏  举报