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

天野星河
这个家伙很勤劳,但还是什么也没有留下搬运于
2025-08-24 22:36:12,当前版本为作者最后更新于2023-04-01 17:04:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
理解题意
这是一个交互题,给定一个长度为 的未知的数列 ,并且保证其单调递增,你可以用任意顺序询问其中至多 个数,并且对于给定的值 和 ,要求从 个数中选出 个数(不能重复),使得它们的和 。
分析
- 先取前 个,然后二分找到序列中最后一个 ,使得 。
- 如果不存在这样的 则无解。
- 如果找到的这样的和恰好 ,则找到一组解。
- 否则,如果存在解则一定可以用 和 中的数得到一组解。
次数为
。
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) extern "C" { long long skim(int i); void answer(vector<int> v); void impossible(); void solve(int n, int k, ll L, int m) { static const int N = 1e6 + 10; assert(m >= 40); if (k > n) return impossible(); static ll a[N]; rep(i, 1, n) a[i] = -1; ll s = 0; rep(i, 1, k - 1) s += a[i] = skim(i); if (s > 2 * L) return impossible(); int l = k, r = n, res = -1; while (l <= r) { int mid = (l + r) >> 1; a[mid] = skim(mid); if (s + a[mid] >= L && s + a[mid] <= 2 * L) { vector <int> t; rep(i, 1, k - 1) t.pb(i); t.pb(mid); return answer(t); } if (s + a[mid] > 2 * L) r = mid - 1; else l = mid + 1, res = mid; } if (res == -1) return impossible(); if (a[k] == -1) a[k] = skim(k); rep(i, max(k + 1, res - k + 1), res) if (a[i] == -1) a[i] = skim(i); static int pos[N], c = 0; rep(i, 1, res) if (~a[i] && (i <= k || i > res - k)) pos[c++] = i; rep(S, 0, (1 << c) - 1) if (__builtin_popcount(S) == k) { ll v = 0; rep(i, 0, c - 1) if (S & (1 << i)) v += a[pos[i]]; if (v >= L && v <= 2 * L) { vector <int> t; rep(i, 0, c - 1) if (S & (1 << i)) t.pb(pos[i]); return answer(t); } } return impossible(); } }审核大大求过…
- 1
信息
- ID
- 6719
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者