题目链接:https://vjudge.net/problem/HDU-6614
题意:建一个树,使得权值和最小,边权为两点的 & 值
题解:对于 i 这个点 假设 二进制位101,那就和2这个点链接,假设为111,那就看一下有没有8这个点,没有的话就和点1连接
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200100;
int f[N], n;
int main() {
int T;
scanf("%d", &T);
ll ans = 0, x;
int flag, cnt;
while(T--) {
scanf("%d", &n);
ans = 0;
for(int i = 2; i <= n; i++) {
x = i;
flag = -1;
cnt = 0;
while(x) {
if(x % 2 == 0 && flag == -1) flag = cnt;
x = x / 2;
cnt ++;
}
if(flag != -1) {
f[i] = (1 << flag);
} else {
if(i != n) {
f[i] = i + 1;
} else {
f[i] = 1;
ans++;
}
}
}
printf("%lld\n", ans);
for(int i = 2; i <= n; i++)
printf("%d%c", f[i], " \n"[i==n]);
}
return 0;
}