异或粽子 题解
首先看到题目中定义的每一个粽子的价值:
选两个整数数
。
满足。
将编号在范围内的所有馅儿混合做成一个粽子。
所得的粽子的美味度为这些粽子的属性值的异或和。
看到有关异或和的问题,首先想到对于
形如这样:xors[i] = xors[i - 1] ^ a[i];
。
这样的话我们可以用
然后把这
所以
接下来我们来看正解的做法:
看到异或最大值,直接想到构建一个
树。
每一次求最大值时优先走和当前位不一样的节点,结合二进制即可发现得出结果最大。
但是这题是求最大的
我们还是先建出
对于数字
和 异或和第 大的结果是什么。
具体统计的话也很简单。
分两种情况进行比较简单的讨论即可。(参照 二叉查找树)
只关心当前的数字个数是否够用,具体可看代码。
Code
#include <bits/stdc++.h>
#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define quad putchar(' ')
#define Enter putchar('\n')
namespace FastIO {
template <class T> void read(T &a) {
T s = 0, t = 1;
char c = getchar();
while ((c < '0' || c > '9') && c != '-')
c = getchar();
if (c == '-')
c = getchar(), t = -1;
while (c >= '0' && c <= '9')
s = (s << 1) + (s <<3) + (c ^ 48), c = getchar();
a = s * t;
}
}
#define int long long
const int N = 500005;
int n, k, a[N], xors[N], d[N];
int dis[N * 35][2], pnum, root = 0, siz[N * 35];
struct Node {
int pos, val;
Node (int _pos = 0, int _num = 0) {
pos = _pos;
val = _num;
}
friend bool operator<(const Node &p, const Node &q) {
return p.val < q.val;
}
};
std::priority_queue <Node> que;
namespace Trie {
inline void insert(int num);
inline int query(int num, int Siz);
}
signed main(void) {
// file("P5283");
std::cin >> n >> k;
for (int i = 1; i <= n; i++)
FastIO::read(a[i]);
for (int i = 1; i <= n; i++)
xors[i] = xors[i - 1] ^ a[i];
Trie::insert(0);
for (int i = 1; i <= n; i++)
Trie::insert(xors[i]);
for (int i = 0; i <= n; i++)
d[i] = 1;
for (int i = 0; i <= n; i++)
que.push(Node(i, Trie::query(xors[i], d[i])));
k *= 2;
int ans = 0;
for (int i = 1; i <= k; i++) {
ans += que.top().val;
int now = que.top().pos;
que.pop();
que.push(Node(now, Trie::query(xors[now], ++d[now])));
}
std::cout << ans / 2 << std::endl;
}
namespace Trie {
inline void insert(int num) {
int now = 0;
for (int i = 31; i >= 0; i--) {
int p = num & (1ll << i);
p = (p != 0);
if (dis[now][p])
now = dis[now][p];
else {
pnum++;
dis[now][p] = pnum;
now = dis[now][p];
}
siz[now] ++;
}
}
inline int query(int num, int Siz) {
int now = 0, ret = 0;
for (int i = 31; i >= 0; i--) {
int p = num & (1ll << i);
p = (p != 0);
if (siz[dis[now][1 - p]] < Siz) {
Siz -= siz[dis[now][1 - p]];
now = dis[now][p];
}
else {
ret += (1ll << i);
now = dis[now][1 - p];
}
}
return ret;
}
}
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】