连续非负整数的异或和

  记 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;

 

综上所述:

{\color{Red} f(1,n)=f(0,n)=\left\{\begin{matrix} n & n\%4=0 \\ 1& n\%4=1\\ n+1& n\%4=2\\ 0& n\%4=3 \end{matrix}\right.}

注:当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 得到的时个位数
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值