Codeforces Round #435 (Div. 2) C. Mahmoud and Ehab and the xor

Mahmoud and Ehab are on the third stage of their adventures now. As you know, Dr. Evil likes sets. This time he won't show them any set from his large collection, but will ask them to create a new set to replenish his beautiful collection of sets.

Dr. Evil has his favorite evil integer x. He asks Mahmoud and Ehab to find a set of n distinct non-negative integers such the bitwise-xor sum of the integers in it is exactly x. Dr. Evil doesn't like big numbers, so any number in the set shouldn't be greater than 106.

Input

The only line contains two integers n and x (1 ≤ n ≤ 1050 ≤ x ≤ 105) — the number of elements in the set and the desired bitwise-xor, respectively.

Output

If there is no such set, print "NO" (without quotes).

Otherwise, on the first line print "YES" (without quotes) and on the second line print n distinct integers, denoting the elements in the set is any order. If there are multiple solutions you can print any of them.

Examples
input
5 5
output
YES
1 2 4 5 7
input
3 6
output
YES
1 2 5

題意:讓你構造一個n個不同元素的集合,使他們異或和等於x。

思路:因爲一個數異或兩次就等於0了,所以 0 ^ 1 ^ 2 ^ 3 ^ ... ^ (n-3) ^ (n-2) ^ ( 0 ^ 1 ^ 2 ^ 3 ^ ... ^ (n-3) ^ (n-2) ^ x) == x

但是(0 ^ 1 ^ 2 ^ 3 ^ ... ^ (n-3) ^ (n-2) ^ x)  可能會跟0 ~ n-2中的某一個重複,所以要改變兩項的值。

題目中的n 是 小於等於1e5的,1e5的二進制是 1100011010100000,是16位,所以我們可以把倒數第二項異或上一個1<<17 或 1<<18 (只要保證異或後的值小於等於1e6就行了),最後一項也異或上同樣的數,這樣既消除了重複,也能得到答案。當然最後一項有可能就是和倒數第二項重複,但是前n-1項都是不同的,那麼最後一項肯定不會和倒數第三項一樣,所以我們就可以改變倒數第三項的值。

需要特殊判定的幾個輸入:

1、當n等於1的時候,答案就是x

2、當n等於2 && x == 0的時候,是不可能有解的,因爲兩個不相同的數異或值不可能等於0


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long

using namespace std;

int a[100010];

int main(void)
{
    int n,x,i,j;
    while(scanf("%d%d",&n,&x)==2)
    {
        if(n == 1)
        {
            printf("YES\n");
            printf("%d\n",x);
            continue;
        }
        if(n == 2 && x == 0)
        {
            printf("NO\n");
            continue;
        }
        a[n-1] = x;
        for(i=0;i<n-1;i++)
        {
            a[i] = i;
            a[n-1] ^= i;
        }
        if(a[n-1] < n-1)
        {
            if(a[n-1] != a[n-2])
                a[n-2] ^= (1<<18);
            else
                a[n-3] ^= (1<<18);
            a[n-1] ^= (1<<18);
        }
        printf("YES\n");
        for(i=0;i<n;i++)
            printf("%d ",a[i]);
        printf("\n");
    }

    return 0;
}


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