1 条题解
-
0
自动搬运
来自洛谷,原作者为

xxr___
CSP-S2025 rp++!搬运于
2025-08-24 23:12:52,当前版本为作者最后更新于2025-04-11 11:54:48,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
简单题,但是有坑。
首先根据异或的性质,一个定值 如果存在一个数 使得 那么这个 是唯一的。
那么我们可以考虑枚举 的度数,然后询问 的值就能推出其他点的度数,因为一个树的度数只和是 的所以只需要判断一下就行,这样就是 的做法。
发现异或实际上就是二进制的某一个两者只有其中一种是
1的时候才会有贡献,所以可以考虑把 的值的二进制下每一位是0是1的数量记录下来,然后询问直接枚举位数就行,这样就是 的了。细节,由于度数不能是 所以你枚举的度数不能存在一个 满足 。
代码:
#include<iostream> const int N = 100005; int n,q,xo[N],t[22],p[22]; bool vs[N << 3]; int main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cin >> n >> q; for(int i = 2;i <= n; ++i){ std::cout << "? "<< 1 <<' '<< i << '\n'; std::cout.flush(); std::cin >> xo[i]; for(int j = 0;j < 21; ++j){ if(xo[i] >> j & 1){ ++ t[j]; }else{ ++ p[j]; } } vs[xo[i]] = 1; } for(int i = 1;i < n; ++i){ int ans = i; for(int j = 0;j < 21; ++j){ if(!(i >> j & 1)){ ans += t[j] * (1 << j); }else{ ans += p[j] * (1 << j); } } if(ans == 2 * n - 2 && !vs[i]){ std::cout << "! "; std::cout.flush(); std::cout << i << ' '; for(int j = 2;j <= n; ++j){ std::cout << (i ^ xo[j]) << ' '; } std::cout.flush(); return 0; } } return 0; }
- 1
信息
- ID
- 11899
- 时间
- 1750ms
- 内存
- 1024MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者