【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;
}

浙公网安备 33010602011771号