XOR World(异或运算)

时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
Let f(A,B) be the exclusive OR of A,A+1,…,B. Find f(A,B).
What is exclusive OR?
Constraints
All values in input are integers.
0≤A≤B≤1e12
输入
Input is given from Standard Input in the following format:
A B

输出
Compute f(A,B) and print it.
样例输入 Copy

2 4

样例输出 Copy

5

提示
2,3,4 are 010, 011, 100 in base two, respectively. The exclusive OR of these is 101, which is 5 in base ten.
这个题就是求区间[A,B]上所有整数的异或。
异或的运算符号用^来表示,异或的运算法则是相同的数异或后为0,不同的数异或后为1。最近在学计算机组成原理中的原码乘法,其中对符号位的处理就是采用两个符号位异或,类似于同号相乘得正(0*0=0,1*1=0),异号相乘得负(1*0=1,0*1=1),我们可以利用这一特点巧妙记住异或的运算公式。
异或的运算性质满足交换律和结合律。特别地,有a^0=0^a=a(1),a^a=0(2)。
回到题目,考虑到题目的数据范围超出了int型,因此要采用O(1)的算法。根据经验,这种题目一般是定义一个solve()函数来求解从0到某个数的某个量,然后利用solve(x2)-solve(x1-1)在O(1)内求出答案。
根据式(1)和式(2),推导过程如下:区间[A,B]的异或=A^(A+1)^(A+2)^(A+3)^...^B=0^A^(A+1)^(A+2)^(A+3)^...^B,其中0=(0^1^2^3^...^(A-1))^(0^1^2^3^...^(A-1)),将此式代入上式得A^(A+1)^(A+2)^(A+3)^...^B=((0^1^2^3^...^(A-1))^(0^1^2^3^...^(A-1)))^A^(A+1)^(A+2)^(A+3)^...^B=(0^1^2^3^...^(A-1))^(0^1^2^3^...^(A-1)^A^(A+1)^(A+2)^(A+3)^...^B),根据上面的分析,显然我们只需要求A-1的前A-1个数异或的结果和B的前B个数异或的结果,然后再将两个结果异或就得到答案
最后一个是求前n个数的异或,我们可以写出0~31的5位字长的二进制表示:

0:0 0 0 0 0
1:0 0 0 0 1 0^1=1
2:0 0 0 1 0 1^2=3
3:0 0 0 1 1 3^3=0
--------------
4:0 0 1 0 0 0^4=4
5:0 0 1 0 1 4^5=1
6:0 0 1 1 0 1^6=7
7:0 0 1 1 1 7^7=0
--------------
8:0 1 0 0 0 0^8=8
9:0 1 0 0 1 8^9=1
10:0 1 0 1 0 1^10=11
11:0 1 0 1 1 11^11=0
--------------
12:0 1 1 0 0 0^12=12
13:0 1 1 0 1 12^13=1
14:0 1 1 1 0 1^14=15
15:0 1 1 1 1 15^15=0
--------------
16:1 0 0 0 0 0^16=16
17:1 0 0 0 1 16^17=1
18:1 0 0 1 0 1^18=19
19:1 0 0 1 1 19^19=0
--------------
20:1 0 1 0 0 0^20=20
21:1 0 1 0 1 20^21=1
22:1 0 1 1 0 1^22=23
23:1 0 1 1 1 23^23=0
--------------
24:1 1 0 0 0 0^24=24
25:1 1 0 0 1 24^25=1
26:1 1 0 1 0 1^26=27
27:1 1 0 1 1 27^27=0
--------------
28:1 1 1 0 0 0^28=28
29:1 1 1 0 1 28^29=1
30:1 1 1 1 0 1^30=31
31:1 1 1 1 1 31^31=0
--------------

通过观察得到,每4个数为一组,数n加上1表示第n+1个数。每组中,第一个数的solve()为它本身,第二个数的solve()为该项与前一项的异或(根据规律可以大胆猜测是1),第三个数的solve()为第四个数,第四个数的solve()为0。根据观察的规律可以写出solve()函数。

#include<stdio.h>
typedef long long int lli;
lli solve(lli x)
{
    if((x+1)%4==0)return 0;
    else if((x+1)%4==1)return x;
    else if((x+1)%4==2)return (x-1)^x;
    else return x+1;
}
int main()
{
    lli a;
    lli b;
    scanf("%lld %lld",&a,&b);
    if(a==0)printf("%lld",solve(b)^solve(0));//A能取到0,因此要特判
    else printf("%lld",solve(b)^solve(a-1));
    return 0;
}

关于异或的应用,可以参考这篇文章异或运算的一些应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值