CF959E 异或和
1 CF959E 异或和
2 题目描述
时间限制 \(2s\) | 空间限制 \(256M\)
\(Ehab\) 对按位异或运算和特殊图运算感兴趣,\(Mahmoud\) 给了他一个融合了这个两类知识的问题。他有一个完全图包含从 \(1\) 到 \(n-1\) 的 \(n\) 个定点。对于所有的 $ 0 ≤ u < v < n$, 定点 \(u\) 和定点 \(v\) 通过权重为 \(u \bigoplus v\) 的无向边连接。请找出最小生成树的权重。最小生成树的权重是所有边的权重之和。
3 题解
我们发现,由于是最小生成树,我们新增加的一个点 \(x\) 可以跟任意一个点连接。也就是说,我们需要找到一个异或与当前点的值最小的点。此时由于之前的所有数都小于当前这个数,我们可以得到的最少价值的边的就是 \(lowbit(x)\)。那么答案就是 \(\sum_{i=1}^{n-1} \limits lowbit(i)\)。
这里,我们设 \(f(i)\) 表示 \(f(i) = lowbit(i)\)。此时,如果 \(i\) 是奇数,那么有 \(f(i) = f(\frac{i-1}{2}) * 2 + \frac{i-1}{2} + 1\),如果 \(i\) 是偶数,那么有 \(f(i) = f(\frac{i}{2}) * 2 + \frac{i}{2}\)。这里我们就可以用递归完成计算。
4 代码(空格警告):
#include <iostream>
using namespace std;
#define int long long
int n;
int sol(int x)
{
if (x == 1) return 1;
if (x == 2) return 3;
if (x & 1) return sol((x-1)/2) * 2 + (x-1)/2 + 1;
else return sol(x/2) * 2 + x/2;
}
signed main()
{
cin >> n;
n--;
cout << sol(n);
return 0;
}