异或运算的简单性质及运用

定义

异或是一种位运算,用符号xor或者^表示。对于运算符左右两侧的数字,对应的二进制位若相同,则该位取0,不同则该位取1.
容易发现,异或运算其实就是二进制下的不进位加法。

性质

  1. 交换律
  2. 结合律
  3. 对于任意数A,有A xor A=0, A xor 0=A
  4. 自反性 A xor B xor B=A

3,4两条性质常常是我们解决异或有关问题的的突破口,下面我们结合几道例题来说明这些性质是如何运用的。

例题

  1. CF1325D
    题意:给定u,v,构造一个长度最小的数组,使数组内各元素异或和为u,元素和为v.
    显而易见,在u>v时无解。u=v时,数组里只有一个元素u。u<v时,根据性质3,我们自然的想到,在数组里先放一个u,再将剩下v-u分成若干个异或和为0的数。若v-u为偶数,则显然我们直接将v-u拆成两个相等的数即可符合要求,此时需要判断拆出的数能否和v-u合并;若v-u为奇数,则将其分成若干个数之后,其异或和的个位必然为1,所以无解。
    具体实现时,注意一些特殊情况的处理,题目样例都已经贴心的给出了这些特殊情况。
    代码:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll u,v;
int main() {
	scanf("%lld %lld",&u,&v);
	if(v == u) {
		if(!u)  printf("0\n");
		else printf("1\n%lld\n",u); return 0;
	}
	if(u > v) {
		printf("-1\n"); return 0;
	}
	if((v-u) % 2 == 0) {
		ll k=(v-u)/2;
		if((k&u) == 0) printf("2\n%lld %lld\n",k,u^k);
		else printf("3\n%lld %lld %lld\n",u,k,k);
	}
	else printf("-1\n");
	return 0;
}
posted @ 2021-11-01 21:01  残碑小筑  阅读(467)  评论(0)    收藏  举报
faults = { minSize : 10, maxSize : 20, newOn : 1000, flakeColor : "#FFFFFF" /* 此处可以定义雪花颜色,若要白色可以改为#FFFFFF */ }, options = $.extend({}, defaults, options); var interval= setInterval( function(){ var startPositionLeft = Math.random() * documentWidth - 100, startOpacity = 0.5 + Math.random(), sizeFlake = options.minSize + Math.random() * options.maxSize, endPositionTop = documentHeight - 200, endPositionLeft = startPositionLeft - 500 + Math.random() * 500, durationFall = documentHeight * 10 + Math.random() * 5000; $flake.clone().appendTo('body').css({ left: startPositionLeft, opacity: startOpacity, 'font-size': sizeFlake, color: options.flakeColor }).animate({ top: endPositionTop, left: endPositionLeft, opacity: 0.2 },durationFall,'linear',function(){ $(this).remove() }); }, options.newOn); }; })(jQuery); $(function(){ $.fn.snow({ minSize: 5, /* 定义雪花最小尺寸 */ maxSize: 80,/* 定义雪花最大尺寸 */ newOn: 200 /* 定义密集程度,数字越小越密集 */ }); });