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

来源:互联网 发布:阿里云搭建ss教程 编辑:程序博客网 时间:2024/06/05 11:03

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
YES1 2 4 5 7
input
3 6
output
YES1 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 longusing 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;}


阅读全文
0 0
原创粉丝点击