牛客练习赛88-C

有关我没开ull见祖宗半个多小时最后还是lnr告诉我这一件事

原题链接
思路:
我们发现:同或这一操作其实就是异或后按位取反。
而一个数按k位取反可以使其异或上2^k - 1
因此,由异或的交换律,我们可以先将这n个数异或起来,最后有若干项是取反的,但我们发现,取反两次则相当于不变,因此最后的结果只有取反一次或者零次,两者答案取最值即可。
AC代码:

#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ll unsigned long long   //开ull
using namespace std;
ll n, k;
ll inp;
ll tmp;
ll sum;
ll qpow(ll x, ll y) {
    ll ret = 1ll;
    while (y) {
        if (y & 1) {
            ret *= x;
        } 
        x *= x;
        y >>= 1;
    }   
    return ret;
}
int main() {
    IO;
    cin >> n >> k;
    tmp = qpow(2, k) - 1;
    for (int i = 1; i <= n; i++) {
        cin >> inp;
        sum ^= inp;
    }
    cout << max(sum, sum ^ tmp) << "\n";
    return 0;
}
posted @ 2021-09-11 20:30  Leins  阅读(69)  评论(0编辑  收藏  举报