51Nod1496 最小异或和

Problem

一个集合包含一组相互不同的数字。现在我们要去寻找一个集合,他要满足如下性质:

对于所有 𝑥(𝑥∈𝑆) ,要满足l ≤ x ≤ r;

1 ≤ |S| ≤ k;

设S中第i个元素是 𝑠𝑖 ;那么 𝑓(𝑆)=𝑠1 ⨁ 𝑠2 ⨁ ... ⨁ 𝑠|𝑆| 的值要尽可能小。

Solution

k=1,答案为l。

k=2,如果偶数-奇数存在为1,但有特殊情况,答案为两者异或和和两个数取最小。

k=3,至少有三个连续的数,则必然<=1,只需要找是否为0,两个数异或不可能为0,考虑l的最高位,记为第i位,如果要全消除,则另外两个数第i位必有1个1,1个0,又第i位为0的数不可能比l小,则此数i+1位为1,那么第i位为1的数第i+1位也为1。

即:
1 1 0 0 0 0 0 0
1 0 X X X X X X
1 X X X X X X ——左边界l

k=4,如果可以选择的数大于4个直接为0,否则4个数暴力找。

Code

#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>

typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll l, r, k;
ll a[10];

int main() {
    io_opt;
    cin >> l >> r >> k;
    if (k == 1) {
        cout << l << endl;
    } else if (k == 2) {
        if (r - l + 1 == 2) {
            cout << min(l, min(r, l ^ r));
        } else {
            cout << "1" << endl;
        }
    } else if (k == 3) {
        int cnt = 0;
        while (l) {
            cnt++;
            l >>= 1;
        }
        if ((3LL << (cnt - 1)) <= r) {
            cout << "0" << endl;
        } else {
            cout << "1" << endl;
        }
    } else {
        if (r - l + 1 > 4) {
            cout << "0" << endl;
        } else {
            a[1] = l, a[2] = l + 1, a[3] = l + 2, a[4] = l + 3;
            ll ans = 1;
            ans = min(ans, a[1] ^ a[2] ^ a[3]);
            ans = min(ans, a[1] ^ a[2] ^ a[4]);
            ans = min(ans, a[1] ^ a[3] ^ a[4]);
            ans = min(ans, a[4] ^ a[2] ^ a[3]);
            ans = min(ans, a[1] ^ a[2] ^ a[3] ^ a[4]);
            cout << ans << endl;
        }
    }
    return 0;
}
posted @ 2019-10-23 17:14  CCWUCMCTS  阅读(266)  评论(0编辑  收藏  举报