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

chlchl
AFOed.搬运于
2025-08-24 22:43:58,当前版本为作者最后更新于2023-01-16 13:53:32,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
唯一打出正解的题,还是得写篇东西纪念一下(
主要是这场比赛是拉满比赛分的关键一场)。题意
求构造一个长度为 的序列,每个数都在 之间,使得前缀、后缀异或和均递增。
Solution
这个题非常像 CF 的 A,构造的签到题。
首先有个贪心的结论,只要我们能够知道最大数的最小值,就能快速判断是否能构造。
考虑异或和持续变大是什么情况。每次异或和若想变大,显然需要将高位的某一位变成 。以此类推, 个数的异或和要想递增,至少需要有 位是 ,这个结果肯定是最小的。
考虑当刚好 位是 ,即前 个数的异或和为 时,每个数是什么。显然每一个数只能够是 ,因为一共只有 位是 ,所以每个数都只能够有一位是 。
题目要求递增,我们就令 ,注意 ,也是符合条件的。
由于异或和只是一个 变换的过程,而且按上面的构造, 之间的位置是不影响的,所以只要前缀和递增,后缀和显然也是递增的。
判断无解也很简单,如果 ,就无解了。
但是注意这东西似乎不能用位运算, 会炸掉,有两种解决方案:一种是使用
__lg函数反向判断(考场用的log2,hack 添加之后就丢精了),即 和 的大小关系;第二种是特判,如果 必定无解()。就喜欢 T1 放这种诈骗了又好像没有诈骗的题目 qwq。
#include<bits/stdc++.h> using namespace std; int T, n; long long m; int main(){ scanf("%d", &T); while(T--){ scanf("%d%lld", &n, &m); if(__lg(m) + 1 >= n){ printf("Yes\n"); for(int i=0;i<n;i++) printf("%lld ", (1ll << i)); printf("\n"); } else printf("No\n"); } return 0; }
- 1
信息
- ID
- 8225
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者