Codeforces Round #628 (Div. 2) D. Ehab the Xorcist

鏈接:http://codeforces.com/contest/1325/problem/D
題意:
找出一個最短的序列,滿足所有元素異或和爲 uu ,和爲vv
思路:
沒有思路。
此題採用 主要採用分類討論和構造的方式來解決:
首先u,vu,v的奇偶性一定相同,下面用反證法來證明:

假設,u,vu,v 的奇偶性不同,不妨設 uu 爲偶數,vv 爲奇數,
uu 分成 若干個數的異或和,那麼這若干個數要麼都是 偶數,要麼有偶數個奇數。(保證最後一位二進制爲0),但這樣一來,這若干個數的和 vv 一定是一個偶數,這和vv 爲奇數矛盾。uu 爲奇數同理。

在滿足奇偶性相同的條件下,再分類討論。

  1. n>vn > v,異或和是不可能大於加法和的,返回-1.
  2. n=vn = v,滿足條件的最短序列就是 nn 本身.
  3. n<vn < v , 首先我們知道 aa ^ a=0aa = 0,a ^ 0=a0 = a,我們根據這個性質來構造一組解:u,(vu)/2,(vu)/2u,(v-u)/2,(v-u)/2,這樣序列的長度就爲3.
    但是還有可能存在 aa ^ b=u,a+b=vb = u,a+b = v的情況,這樣長度就只是2,所以要將這種情況特判一下。

根據Leetcode 371 不用加號的A+B,異或是不進位的加法,我們可以知道:加法 = 異或+進位部分,即 a+b=aa+b = a ^ b+2(ab+2(a & b)b)。本題中,u=au = a ^ bb,就可以的得到 a+b=u+2(aa+b =u+2(a & b)b),繼續推 (a(a & b)=(vu)/2b)=(v-u)/2,此時可以知道 (vu)/2(v-u)/2 二進制位上爲 1 的位置,a,ba,b對應位置的二進制也爲 1 ,uu 對應的二進制爲 0 ,可以得出當
(vu)/2(v-u)/2 上所有爲1的二進制位,uu 對應的二進制位都爲 0的時候(即(vu)/2(v-u)/2 & u==0u==0),長度爲 2 個,可以將序列構造爲 u+(uv)/2,(uv)/2u+(u-v)/2,(u-v)/2

同時因爲題目要求,輸出的序列爲正整數 所以 特判一下u=v=0u = v = 0的情況。

最後還要注意的是:運算符 “^” 的 優先級是低於 "=="的
在這裏插入圖片描述

/*****************************
*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;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章