NC18979 毒瘤xor
题目
题目描述
小a有 个数 ,给出 个询问,每次询问给出区间 ,现在请你找到一个数 ,使得
- 最大, 表示异或操作(不懂的请自行百度)
输入描述
第一行一个整数 ,表示序列的长度
第二行 个整数,表示序列内的元素
第三行一个整数 ,表示询问的个数
接下来 行,每行两个整数 ,表示询问的区间
输出描述
输出 行,每行一个整数表示答案
若有多组可行解,请输出较小的解
示例1
输入
5 4 78 12 1 3 3 2 5 1 4 3 3
输出
2147483632 2147483635 2147483635
备注
对于 的数据,
对于 的数据,
对于 的数据,
保证
题解
知识点:贪心,位运算。
显然不能每次枚举,需要更快的贪心方法构造一个 。
对于位运算的贪心,只需要让每位到达最优就行,因为互相独立。因此,本题只要对于 的每一位产生的和最大即可。
考察所有 某一位,要让这位异或和最大,就要考虑这位的 和 的数量,如果 多,则 这位应为 ,否则为 。这里可以用二维数组 代表 的数字中第 位是 的数量,前缀和预处理即可。
但要注意的是,我们要求最小的 ,因此在两者皆可时 更优,即 的数量为严格小于一半时就用 。这里不能用 sum[r][i] - sum[l - 1][i] < (r - l + 1)/2
,因为这是取下整,要取上整。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; int a[100007], sum[100007][31]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; for (int i = 1;i <= n;i++) { for (int j = 0;j < 31;j++) { if (a[i] & (1 << j)) sum[i][j]++; sum[i][j] += sum[i - 1][j]; } } int q; cin >> q; while (q--) { long long l, r; cin >> l >> r; int x = 0; for (int i = 0;i < 31;i++) { if (2 * (sum[r][i] - sum[l - 1][i]) < r - l + 1) x |= (1 << i);///这里要除的话取上整 } cout << x << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16384066.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧