记 f(x, y) 为x到y的所有整数的异或值。
f(1,n) = f(0,n);
当n为2^k-1(2的K次方减一)时;
0 到 2^k-1 共2^k个数 等于∑C(n,i)
可以看做在k个位置中放入i个0,最后求和
同时可以看做在空格位置中放入i个1;最后求和
即在每一位上1个0的个数都相等,每个位上有2^(k-1)个1,当k>=2时 1的个数为偶数;
而我们已经知道偶数个1的异或和为0
所以 f(0, 2^k - 1) = 0 (k >= 2)
对 f(0, n) (n>=4) 设n的最高位1是在第k位(k >= 2),
f(0, n) = f(0, 2^k - 1) xor f(2^k, n) = f(2^k, n])
对2^k到n这n+1-2^k个数,最高位(第k位)共有 m = n+1-2^k 个1,(因为最高位都是1)
2^k总是偶数,因此,当n为奇数时,m是偶数,f(0, n) = f(2^k, n) = f(0, n - 2^k) 继续递推
当n为奇数(n - 2^k)总是奇数 ,所以:f(0,n) = f(0,n-2^k-2^(k-1)...-2^2) (因为k>=2,所以减到最小的是4,剩下两位不知道)
此时只剩下两位是我们需要的 我们可以用(n & 3)很快得到后两位
由于n是奇数 所以(n & 3)只可能得到 1 或 3;
1对应 二进制数 (01)所以是奇数个1 此时f (0,n)=1;
3对应 二进制数 (11) 此时f(0,n)=0;
当n为偶数时,m是奇数,因而 f(0, n] = f(2^k, n) = f(0, n - 2^k) xor 2^k 继续递推
可得:f(0, n) = f(0, n & 3) xor 2^k xor n[k]*2^(k-1) xor ....n[2]*2^2 (n[k] 为 n的二进制数的第k位)(同上,同样剩下最后两位不知道);
很明显 当n为偶数时 f[0,n]的二进制从最高位到第3位(如果不止3位) 跟n的二进制数从高位到第三位 相同;
此时只需要 判断 第二位
n & 3=0对应后二位为(00) 此时 f[0,n]=n;
n & 3=2对应后二位为(10) 此时 f[0,n]=n+1;
综上所述:
注:当n大于4时,n%4与n&3是等价的
最后有
f(x,y)=f(0,y) xor f(0,x-1) (x>0)
实现代码
This is the code:
int xor_n(int n)//从1到n的异或和
{
int t = n & 3;
if (t & 1) //当mod4为3或者1时,判断返回
return t / 2 ^ 1;
else //当mod4为0或者2时,判断返回
return t / 2 ^ n;
//t/2 得到的时个位数
}