专栏文章
题解:P12025 [USACO25OPEN] Sequence Construction S
P12025题解参与者 5已保存评论 4
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mipm8v0m
- 此快照首次捕获于
- 2025/12/03 14:18 3 个月前
- 此快照最后确认于
- 2025/12/03 14:18 3 个月前
题意简述
构造序列使得:
- 。
- 。
- 。
若无解输出 。
基本思路
因为 是一堆东西的异或和,不难想到对 进行二进制分解。
以 为例,。
对于第一位 ,它由一个 满足 贡献而来,这个 最小为 ,故我们将 加入序列,同样的对于最后一位 ,将 加入序列。
该样例对应的 ,减去 和 后还剩下 。
我们需要之后的元素 的个数异或和为 。
是一个奇数,因为 和 二进制下都只含一个 ,我们先从中取出一个 和一个 ,再取出两个 。
对于一个偶数,直接取两个 则满足条件。
考虑无解情况,若 在某一步小于了 ,则无解。
若剩余的 为 ,如果当前序列有一个 ,改为 可以凑出一组解,否则无解。
AC Code
CPP#include <bits/stdc++.h>
#define F(i, a, b) for (int i = a; i <= b; ++i)
#define _F(i, a, b) for (int i = a; i >= b; --i)
#define ll long long
using namespace std;
ll rd() {
ll p = 0, f = 1; char ch = getchar();
while (ch>'9' || ch<'0') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch>='0' && ch<='9') p = p*10+ch-'0', ch = getchar();
return p * f;
}
ll m, k, a[110], tot = 0;
void Solve() {
tot = 0;
m = rd(), k = rd();
_F(i, 5, 0) {
if (k & (1<<i)) {
ll cur = (1<<(1<<i))-1;
m -= cur, a[++tot] = cur;
if (m < 0) {
cout << -1 << '\n';
return ;
}
}
}
if (m == 1) {
if (a[tot] != 1) {
cout << -1 << '\n';
return ;
}
++a[tot];
} else if (m % 2 == 0) {
a[++tot] = m/2, a[++tot] = m/2;
} else {
a[++tot] = 1, a[++tot] = 2, a[++tot] = (m-3)/2, a[++tot] = (m-3)/2;
}
cout << tot << '\n';
F(i, 1, tot) cout << a[i] << ' ';
cout << '\n';
}
int main() {
ll T = rd(); while (T--) Solve();
return 0;
}
相关推荐
评论
共 4 条评论,欢迎与作者交流。
正在加载评论...