CF1625D.Binary Spiders
大概就是给出 个数和 ,要从中选最多的数使得两两异或值大于等于
输出方案
一开始的想法很复杂、、、
其实用到一个结论就做好了
对于一个升序数列,它们两两间的异或最小值就是相邻数的异或最小值
于是可以先排序,再
设 表示到第 位强制选 能选出最多的数的数量
那么
于是优化这个 的 即可
这就是个很简单的事
考虑 的选取
若 ,那么异或值从高位到低位一部分等于 ,然后在某一位大于
那么我们从高到低枚举位数,考虑在这一位之前等于 ,统计这一位大于 的贡献
讨论 和 这一位的 值,发现可行数值区间是连续的,权值线段树即可
最后再处理 的贡献
#include <cstdio> #include <iostream> #include <algorithm> #define RE register #define IN inline using namespace std; typedef long long LL; const int N = 3e5 + 5; int n, m, f[N], g[N], Len, size, rt; struct node{int v, id;}a[N]; IN bool cmp(node a, node b){return a.v < b.v;} int seg[N * 31], ls[N * 31], rs[N * 31]; void Modify(int &p, int l, int r, int x, int v) { if (!p) p = ++size; if (l == r) return seg[p] = v, void(); int mid = l + r >> 1; if (x <= mid) Modify(ls[p], l, mid, x, v); else Modify(rs[p], mid + 1, r, x, v); if (f[seg[ls[p]]] > f[seg[rs[p]]]) seg[p] = seg[ls[p]]; else seg[p] = seg[rs[p]]; } int Query(int p, int l, int r, int x, int y) { if (x > r || y < l) return 0; if (x <= l && r <= y) return seg[p]; int mid = l + r >> 1, L = 0, R = 0; if (ls[p] && x <= mid) L = Query(ls[p], l, mid, x, y); if (rs[p] && y > mid) { R = Query(rs[p], mid + 1, r, x, y); if (!L) L = R; else{ if (f[L] > f[R]) return L; return R; } } return L; } int main() { scanf("%d%d", &n, &m); for(RE int i = 1; i <= n; i++) scanf("%d", &a[i].v), a[i].id = i; sort(a + 1, a + n + 1, cmp), Len = a[n].v; int ans = 1, pos = 0, pre, cur; for(RE int i = 1; i <= n; i++) { f[i] = 1, pre = 0; for(RE int j = 30; j >= 0; j--) { if ((m >> j) & 1){if (!((a[i].v >> j) & 1)) pre |= (1 << j);} else{ if ((a[i].v >> j) & 1) { cur = Query(rt, 0, Len, pre, pre + (1 << j) - 1), pre |= (1 << j); if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur; } else{ cur = Query(rt, 0, Len, pre + (1 << j), (LL)pre + (1LL << j + 1) - 1); if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur; } } if (!j) { cur = Query(rt, 0, Len, pre, pre); if (f[cur] + 1 > f[i]) f[i] = f[cur] + 1, g[i] = cur; } } if (ans < f[i]) ans = f[i], pos = i; if (i < n) Modify(rt, 0, Len, a[i].v, i); } printf("%d\n", (ans == 1) ? -1 : ans); if (ans > 1) while (pos) printf("%d ", a[pos].id), pos = g[pos]; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App