求1到n这n个整数间的异或值 (O(1)算法)
问题:求1到n这n个整数间的异或值,即 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 (t & 1) return t / 2u ^ 1;
return t / 2u ^ n;
}
出处:http://www.cnblogs.com/flyinghearts/
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
求1到n这n个整数间的异或值 (O(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阶斐 ...
- 求任意长度数组的最大值(整数类型)。利用params参数实现任意长度的改变。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Java 整数间的除法运算如何保留所有小数位?
1.情景展示 double d = 1/10; System.out.println(d); 返回的结果居然是0.0!这是怎么回事儿? 2.原因分析 第一步:你会发现用运算结果也可以用int类型接 ...
- 求1到n,n个整数的全排列
package com.dong.harder; public class AllArrays { public static void main(String[] args) { // TODO A ...
- 线性基求第k小异或值
题目链接 题意:给由 n 个数组成的一个可重集 S,每次给定一个数 k,求一个集合 \(T \subseteq S\), 使得集合 T 在 S 的所有非空子集的不同的异或和中, 其异或和 \(T_1 ...
- python中的整数、浮点数和布尔值
整数和浮点数有那个四则运算: 两种类型的数可以直接进行加减,当整数和浮点数进行加减的时候,结果会自动的变为浮点数,其中除法运算是“/”来表示的, 而余数的算术符号是“%”来表示的. 在布尔值的判断中我 ...
- 给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)
第一种方法: 计数排序后,然后找出两两之间的最大差值 计数排序的时间复杂度是O(N) public class CountSort { public static void main(String[] ...
- 求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法
原理 数据结构 // GO private static Map<Map<Integer,String>,Integer> GO = new HashMap<Map< ...
- C_输入一个整数N,输出从0~N(算法思考)
1.for循环实现 #include <stdio.h> #include <time.h> clock_t start, stop; double duration; voi ...
随机推荐
- centos6.5下,使用虚拟ftp用户
因为业务的问题,有位客户的账户总是出现各种问题,本人对于acl的使用又不是很会,所以和同事一起研究了一下这个虚拟ftp用户. Centos6.5 1 需求 为了保证系统的安全性,现对系统中vsftpd ...
- Java HashSet和ArrayList的查找Contains()时间复杂度
今天在刷leetCode时,碰到了一个题是这样的. 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 看到 ...
- webpack 配置es6 语法
使用babel来编译es6的语法; 1.在终端上输入指令 npm install webpack babel-loader babel-core babel-preset-es2015 --save- ...
- Download QT
http://download.qt.io/archive/qt/
- thinkphp 替换入口
3.2版本支持根据当前的运行环境生成Lite文件,可以替换框架的入口文件或者应用入口文件,提高运行效率. 我们的建议是在生产环境中关闭调试模式后生成Lite文件.注意,目前SAE平台不支持直接生成Li ...
- Android下载Android源码
使用Git,命令是:git clone http://android.googlesource.com/platform/frameworks/base.git
- sqoop2安装总结
sqoop2安装 1. 下载解压缩 此次安装版本为1.99.6 # Decompress Sqoop distribution tarball tar -xvf sqoop-<version&g ...
- Spring源码由浅入深系列五 GetBean
获取bean的过程如上图所示.下一章将继续图示讲解createBean的过程.
- 3.7.4 Tri0 and tri1 nets
Frm: IEEE Std 1364™-2001, IEEE Standard Verilog® Hardware Description Language The tri0 and tri1 net ...
- 内置Jetty配置JSP支持过程中的常见报错
目录 1. 常见报错及解决 1.1 JSP support not configured 1.2 JSTL标签解析 1.3 JSP编译 1.4 JSP实现依赖 1.5 EL表达式支持 2. 小结 1. ...