问题:求1nn个整数间的异或值,即 1 xor 2 xor 3 ... xor n

记 f(x, y) 为x到y的所有整数的异或值。

对 f(2^k, 2^(k+1) -1) (注意文章中的 ^ 表示的是“幂”,xor 表示“异或”,or 表示“或”):

2^k 到 2^(k+1) -1 这2^k个数,最高位(+k位)的1个数为2^k,

若 k >= 1,则2^k为偶数,将这2^k个数的最高位(+k位)去掉,异或值不变。

因而 f(2^k, 2^(k+1) -1) = f(2^k - 2^k, 2^(k+1) -1 -2^k) = f(0, 2^k -1)

因而 f(0, 2^(k+1) -1) = f(0, 2^k -1) xor f(2^k, 2^(k+1) -1) = 0 (k >= 1)

即 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

当n为奇数时,m是偶数,因而 f(0, n) = f(2^k, n) = f(0, n - 2^k)

由于n - 2^k 与 n同奇偶,递推上面的公式,可得:f(0, n) = f(0, n % 4)

当 n % 4 == 1 时, f(0, n) = f(0, 1) = 1

当 n % 4 == 3 时, f(0, n) = f(0, 3) = 0

当n为偶数时,m是奇数,因而 f(0, n) = f(2^k, n) = f(0, n - 2^k)  or  2^k

也就是说,最高位1保持不变,由于n - 2^k 与 n同奇偶,递推上面的公式,

可得:f(0, n) = nn or  f(0, n % 4)   (nn为 n的最低2位置0)

当 n % 4 == 0 时, f(0, n) = n

当 n % 4 == 2 时, f(0, n) = nn or  3 = n + 1 (公式对 n = 2仍成立)

综上所述:

f(1, n)  =  f(0, n)  =

n      n % 4 == 0

1      n % 4 == 1

n +1   n % 4 == 2

0      n % 4 == 3

代码:

unsigned xor_n(unsigned n)

{

unsigned t = n & 3;

if (& 1) return t / 2u ^ 1;

return t / 2u ^ n;

}

作者:flyinghearts
出处:http://www.cnblogs.com/flyinghearts/
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

求1到n这n个整数间的异或值 (O(1)算法)的更多相关文章

  1. 【严蔚敏】【数据结构题集(C语言版)】1.17 求k阶斐波那契序列的第m项值的函数算法

    已知k阶斐波那契序列的定义为 f(0)=0,f(1)=0,...f(k-2)=0,f(k-1)=1; f(n)=f(n-1)+f(n-2)+...+f(n-k),n=k,k+1,... 试编写求k阶斐 ...

  2. 求任意长度数组的最大值(整数类型)。利用params参数实现任意长度的改变。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. Java 整数间的除法运算如何保留所有小数位?

      1.情景展示 double d = 1/10; System.out.println(d); 返回的结果居然是0.0!这是怎么回事儿? 2.原因分析 第一步:你会发现用运算结果也可以用int类型接 ...

  4. 求1到n,n个整数的全排列

    package com.dong.harder; public class AllArrays { public static void main(String[] args) { // TODO A ...

  5. 线性基求第k小异或值

    题目链接 题意:给由 n 个数组成的一个可重集 S,每次给定一个数 k,求一个集合 \(T \subseteq S\), 使得集合 T 在 S 的所有非空子集的不同的异或和中, 其异或和 \(T_1 ...

  6. python中的整数、浮点数和布尔值

    整数和浮点数有那个四则运算: 两种类型的数可以直接进行加减,当整数和浮点数进行加减的时候,结果会自动的变为浮点数,其中除法运算是“/”来表示的, 而余数的算术符号是“%”来表示的. 在布尔值的判断中我 ...

  7. 给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)

    第一种方法: 计数排序后,然后找出两两之间的最大差值 计数排序的时间复杂度是O(N) public class CountSort { public static void main(String[] ...

  8. 求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法

    原理 数据结构 // GO private static Map<Map<Integer,String>,Integer> GO = new HashMap<Map< ...

  9. C_输入一个整数N,输出从0~N(算法思考)

    1.for循环实现 #include <stdio.h> #include <time.h> clock_t start, stop; double duration; voi ...

随机推荐

  1. unix, PF_UNIX, AF_UNIX, PF_LOCAL, AF_LOCAL - 用于本地内部进程通讯的套接字。

    SYNOPSIS(总览) #include <sys/socket.h> #include <sys/un.h> unix_socket = socket(PF_UNIX, t ...

  2. ubuntu系统设置密码报错 Module is unknown

    修改账户密码报错 # passwd 报错信息 passwd: Module is unknown passwd: password unchanged   修改配置文件 # cd /etc/pam.d ...

  3. jdbc打印sql语句-p6spy配置

    @Configuration public class P6SpyConfig { /** * P6数据源包装, 打印SQL语句 */ @Bean public P6DataSourceBeanPos ...

  4. C#反射从入门到放弃(这部分遇到的新东西太多了让人接受不能)

    首先,我们需要知道type,type是类型的类型(笑 官方点的说法是,BCL声明了一个Type抽象类,它被设计用来包含类型的特性, 使用这个类的对象(抽象类的对象?这显然是错误的,但是这里用的其实是T ...

  5. C# 类中访问修饰符的优先级与用法(public, internal, protected, private)

    首先:类成员的访问级别是以类的访问级别为上限的! 也就是类的访问级别低时,类成员的访问级别高也无法突破类的访问级别 public级别,作用域是这个解决方案() internal级别,作用域是整个装配集 ...

  6. delphi常见的错误

    ******************************* * 编 译 错 误 信 息 * ******************************* ';' not allowed befo ...

  7. js基础用法 ,基础语法

    js用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 <body> 和 <head& ...

  8. 线段树区间离散化——牛客多校E

    这个区间离散化把我调死了.. 总之用vector来离散化,然后叶子节点维护的是一段区间,记录下每个叶子结点的起点+长度 千万要注意下标不能弄错! #include<bits/stdc++.h&g ...

  9. NOIp2018集训test-9-23

    这个NOI模拟题怕是比你们的NOIp模拟题要简单哦.. 友好的生物 应该是一道简单题,但是机房只有辉神一个人想到正解似乎. 被我kd-tree水过去了(这不是kd-tree的裸题吗???(不是)) / ...

  10. (转)linux下装tomcat

    转载于:http://www.linuxidc.com/Linux/2016-11/136959.htm (linux社区) 1 tomcat介绍 Tomcat 是由 Apache Foundatio ...