SDNU - 1385.Problem A: XOR
http://www.acmicpc.sdnu.edu.cn/problem/show/1385
Description
Problem A: XOR
Given two integers S and F, what is the XOR (exclusive-or) of all numbers between S and F (inclusive)?
Input
The first line of input is the integer T, which is the number of test cases (1 ≤ T ≤ 1000). T lines follow, with each line containing two integers S and F (1 ≤ S ≤ F ≤ 1 000 000 000).
Output
For each test case, output the (decimal) value of the XOR of all numbers between S and F, inclusive.
Sample Input
5
3 10
5 5
13 42
666 1337
1234567 89101112
Sample Output
8
5
39
0
89998783
题意:
给出一个S和一个F,求S^(S+1)^(S+2)^…^F的值。
题意很简单,求的东西就很迷糊了。
在这种没有头绪的情况下,考虑一下这一类东西的一般形式,这个题是要求S^S+1^S+2^….^F,那么两个数的异或是什么样子的??是否有什么规律??研究一下这种特殊情况,然后再延伸到一般情况,也是有可能得出答案的。
首先我们需要的是异或的基本知识。
a^b^c==(a^b)^c==a^(b^c) (异或没有顺序区分)—-*①
a^0==a (一个数异或0还是本身)—-②
a^a==0 (相同的数异或为0)—-③
a^b^b==a (异或一个数两次等于没有异或,可以由①②推出)—-④
先找几组基本的两项异或。
00^01==01 01^02==03 02^03==01 03^04==07
04^05==01 05^06==03 06^07==01 07^08==15
08^09==01 09^10==03 10^11==01 11^12==07
12^13==01 13^14==03 14^15==01 15^16==31
16^17==01 17^18==03 18^19==01 19^20==07……
第二排具有一个性质,第四排的性质也可以找,为了简便我找第一排和第三排的性质。
我们把这些数提取出来发现:
0^1 2^3 4^5 6^7 8^9 ……..最后的结果都是1。
现在我们考虑我们最初的命题。
由给出的①和④可以把S^(S+1)^(S+2)^…^F写成(1^2^3^4^…^(S-1))^(1^2^3^4^…^S^(S+1)^……^F)
那我们需要算的只是1^2^3^…^(S-1)和1^2^3^…..^F
变形为0^1^2^3^…^(S-1)和0^1^2^3^…..^F
只需要看S-1和F各自的性质了。
若F是偶数,那么F-1是奇数,就需要看0~F-1中可以分成k组,这代表了k个1的异或,如果是奇数组结果就是1与F异或,如果是偶数组就是0与F的异或;若F是奇数,那么需要看的是0~F中可以分成的k组,同样代表了k个1的异或,如果是奇数组结果就是1,如果是偶数组结果就是0。
S-1的计算同样。
这样算出来了1^2^3^….^(S-1)和1^2^3^…..^F,再把这两个数异或就可以得出答案了。
代码如下:
#include <stdio.h>
int main()
{
long long S, F, f, n, m, T, i, s, k;
while (scanf("%lld", &T) !=EOF)
{
for (i = 0; i < T; i++)
{
scanf ("%lld %lld", &S, &F);
if (S != F)
{
S = S - 1;
if (F%2 == 1)
{
n = (F+1)/2%2;
f = n;
}
else
{
n = (F-1)/2%2;
f = F + n;
}
if (S%2 == 1)
{
m = (S+1)/2%2;
s = m;
}
else
{
m = (S-1)/2%2;
s = S + m;
}
k = f ^ s;
}
else
{
k = S ^ F;
}
printf ("%lld\n", k);
}
}
return 0;
}