CodeForces - 862C(構造)

題意:

讓你輸出一個長度爲 n 的數組,這個數組所有元素異或和要等於 x。

題解:

首先我們要知道:x ^ y ^ (x ^ y) = 0,這樣我們就可以推出:x ^ y ^ (x ^ y ^ z) = z => x ^ y ^ z ^ (x ^ y ^ z ^ m) = m。

因此,我們可以通過這樣去構造一個數組,假如:1,2,...,n - 3,保留後三位,前面從 1 到 n - 3 輸出,該異或和爲Z。則Z ^ X ^ Y ^ (X ^ Y ^ Z ^ x) = x,因爲元素不能超過 1e6(20位)並且 x <= 1e5,所以 X 和 Y 取17 18 19 位爲0都可以,我選擇取了 X = 1 << 17,Y = 1 << 18。

這裏爲什麼取 x ^ y ^ z ^ (x ^ y ^ z ^ m) = m 這條公式,而不是 x ^ y ^ (x ^ y ^ z) = z,因爲前面異或和可能就已經等於 x 了,會導致最後一位和最後第二位一樣的可能,所以不能選取。我們選取的公式可以保證最後一個數和前面的數不一樣,因爲有兩位一定爲 1,無論 1 到 n - 3 異或和是不是爲 x 都無所謂。

AC代碼:

#include <algorithm>
#include  <iostream>
#include   <cstdlib>
#include   <cstring>
#include    <cstdio>
#include    <string>
#include    <vector>
#include    <bitset>
#include     <stack>
#include     <cmath>
#include     <deque>
#include     <queue>
#include      <list>
#include       <set>
#include       <map>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define line printf("---------------------------\n")
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1000+10;

int main() {
	int n, x;
	while(cin >> n >> x) {
		if(n == 1) {
			cout << "YES" << endl << x << endl;
		} else if(n == 2) {
			if(x == 0) {
				cout << "NO" << endl;
			} else {
				cout << "YES" << endl << 0 << " " << x << endl;
			}
		} else {
			cout << "YES" << endl;
			int X = 1 << 17, Y = 1 << 18, Z = 0;
			for(int i = 1; i <= n - 3; i++) {
				cout << i << " ";
				Z ^= i;
			}
			cout << X << " " << Y << " " << (X ^ Y ^ Z ^ x) << endl;
		}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章