鏈接:http://codeforces.com/contest/1325/problem/D
題意:
找出一個最短的序列,滿足所有元素異或和爲 ,和爲。
思路:
沒有思路。
此題採用 主要採用分類討論和構造的方式來解決:
首先的奇偶性一定相同,下面用反證法來證明:
假設, 的奇偶性不同,不妨設 爲偶數, 爲奇數,
將 分成 若干個數的異或和,那麼這若干個數要麼都是 偶數,要麼有偶數個奇數。(保證最後一位二進制爲0),但這樣一來,這若干個數的和 一定是一個偶數,這和 爲奇數矛盾。 爲奇數同理。
在滿足奇偶性相同的條件下,再分類討論。
- ,異或和是不可能大於加法和的,返回-1.
- ,滿足條件的最短序列就是 本身.
- , 首先我們知道 ^ ^ ,我們根據這個性質來構造一組解:,這樣序列的長度就爲3.
但是還有可能存在 ^ 的情況,這樣長度就只是2,所以要將這種情況特判一下。
根據Leetcode 371 不用加號的A+B,異或是不進位的加法,我們可以知道:加法 = 異或+進位部分,即 ^ & 。本題中, ^ ,就可以的得到 & ,繼續推 & ,此時可以知道 二進制位上爲 1 的位置,對應位置的二進制也爲 1 , 對應的二進制爲 0 ,可以得出當
上所有爲1的二進制位, 對應的二進制位都爲 0的時候(即 & ),長度爲 2 個,可以將序列構造爲 。
同時因爲題目要求,輸出的序列爲正整數 所以 特判一下的情況。
最後還要注意的是:運算符 “^” 的 優先級是低於 "=="的
/*****************************
*author:ccf
*source:cf round 628-D
*topic:
*******************************/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define ll __int64
using namespace std;
const int N = 1e5;
ll u,v,cas;
int main(){
//freopen("data.in","r",stdin);
scanf("%I64d %I64d",&u,&v);
if((u & 1) != (v & 1)){
puts("-1");
return 0;
}
if(u == 0 && v == 0){
printf("0");
return 0;
}
if(u > v){
printf("-1");
}else if(u == v){
printf("1\n%I64d\n",u);
}else{
if((u & (v - u)/2) == 0){//注意此處優先級
printf("2\n%I64d %I64d",(u+v)/2,(v-u)/2);
}else{
printf("3\n%I64d %I64d %I64d",u,(v-u)/2,(v-u)/2);
}
}
return 0;
}