题单
前言
将十进制整数转换为二进制后,有很多按位运算的运算符。如果能善于利用位运算的一些性质,往往能达到事半功倍的效果。
P5514 [MtOI2019]永夜的报应
思路
- 我们用 t k t_k tk 表示 2 k 2^k 2k 在所有数中出现的次数。若 t k t_k tk 为奇数,则无论如何分组,权值和中 2 k 2^k 2k 都无法消除。于是考虑最小化 t k t_k tk 为偶数时, 2 k 2^k 2k 对权值和的影响,易得,分为一组即可完全消除其影响。故最后的答案便是 a i a_i ai 的异或和。
- 时间复杂度为 O ( n ) \mathcal O(n) O(n)。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 100;
int a[maxn], n;
void read (int &x)
{
x = 0; int w = 1;
char ch = getchar ();
while (ch < '0' || ch > '9')
{
if (ch == '-') w = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + ch - 48;
ch = getchar ();
}
}
int main ()
{
read (n);
int sum = 0;
for (int i = 1; i <= n; i++)
read (a[i]), sum ^= a[i];
printf ("%d", sum);
return 0;
}
收获
- 分奇偶讨论的思想。