Codeforces Round #435 C

Mahmoud and Ehab and the xor

题意:问是否存在n个不同的非负整数的异或和为x

思路:先拿出一个x来,则问题变成了n-1个不同的数异或和为0(n-1个数不为x),将数字化为二进制,不难发现,位数为3的全部的数的异或和为0(4^5^6^7=0),位数为4.5.6.7...都是如此,位数为1的除去0,也是如此,只有位数为2的异或和不为0,那么可以把n-1化成二进制 2^a1+2^a2+2^a3...,如n-1=6=2^2+2^1,表示6是由4和2组成的,即把n-1分为2部分,其中4个数异或和为0,另外2个数异或和也为0,由前面可知,位数为3的数一共4个,异或和为0,位数为2的异或和不为0,那么可以把这2个数再提出来,其他保持不变,即得到了一个n-3个数异或和为0,那么剩下3个数异或和为x,可另其余3个数分别为 x+2^17+2^19, x+2^17, x+2^19

AC代码:

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#pragma comment(linker, "/STACK:102400000,102400000")
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("
")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

int bit[100],ans[N];
int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n, x; cin>>n>>x;
    if(n==2 && x==0) {cout<<"NO
"; return 0;}
    int t=n-1,l=0,x1,x2,x3,f=0,k=0;
    while(t){
        bit[l++]=t%2;
        t>>=1;
    }
    x1=x+(1<<19)+(1<<17);
    x2=x+(1<<19);
    x3=x+(1<<17);
    if(bit[1]==0){
        cout<<"YES
";
        ans[++k]=x;
        for(int i=0; i<l; ++i){
            if(bit[i]){
                for(int j=1<<i; j<(1<<(i+1)); ++j){
                    if(f-- > 0) ans[++k]=j+(1<<19);
                    else ans[++k]=(j==1?0:j);
                    if(ans[k]==x) f=1, ans[k]+=(1<<19);
                }
            }
        }
    }
    else{
        cout<<"YES
";
        ans[++k]=x1,ans[++k]=x2,ans[++k]=x3;
        for(int i=0; i<l; ++i){
            if(bit[i]){
                if(i==1) continue;
                for(int j=1<<i; j<(1<<(i+1)); ++j){
                    ans[++k]=(j==1?0:j);
                }
            }
        }
    }
    if(ans[k]>=(1<<19) && ans[k-1]<(1<<19)) ans[k-1]+=(1<<19);
    for(int i=1; i<=k; ++i) cout<<ans[i]<<" ";
    return 0;
}
原文地址:https://www.cnblogs.com/max88888888/p/7567972.html