位运算

(十二)golang--进制和位运算

﹥>﹥吖頭↗ 提交于 2019-12-04 06:29:15
1.基本进制 (1)二进制:0,1,满2进1 在golang中,不能直接使用一个二进制表示一个整数,可以用八进制、十进制和十六进制表示 (2)十进制:0-9,满10进1 (3)八进制:0-7,满8进1,以数字 0 开头 (4)十六进制:0-9及A-F,满16进1,以 0x或0X 开头,此处A-F不区分大小写,例如0x21AF+1=0x21B0 package main import "fmt" func main() { var i int = 5 fmt.Printf("%b \n", i) //这里^表示几次方 //转成十进制为:8^1+8^0=9 var j int = 011 fmt.Println("j=", j) //转成十进制:16^1+16^0=17 var k int = 0x11 fmt.Println("k=", k) } 2.进制之间的转换 (1)其它进制转十进制   次方相加   比如:二进制1011转为十进制:2^3+2^1+2^0=11      八进制23转为十进制:2*(8^1)+3*(8^0)=16+3=19 (2)十进制转其他进制   除法取余   11转二进制:11除以2,商为5,余数为1;5除以2,商为2,余数为1;2除以2,商为1,余数为0;1除以2,商为0,余数为1,;当商为零时,余数从后往前排列:1011 (3)二进制转八进制

[LeetCode]巧用位运算

て烟熏妆下的殇ゞ 提交于 2019-12-04 05:04:58
在编程过程中,位运算是常用的运算之一,直接对二进制位操作使得位运算比一般的操作指令更加高效。巧用位运算,可以解决一些其他运算符号难以解决或者用其他方法解决起来更加复杂的问题。 1.二进制数字中“1”的位数 int get_1_Count(int n) { int count = 0; while (n) { n = n&(n-1); count++; } return count; } 2.两个数作加法运算 不使用 “+” 运算符的条件下对两个输入参数做加法运算,位运算也可以做到!那就是 异或 ! a^b:按位相加后没有进位的和; a&b:可得可以产生进位的地方; (a&b)<<1:得到进位后的值。 int get_sum_by_bitAdd(int a, int b) { int aTemp = 0, bTemp = 0; while (b != 0) { aTemp = a ^ b; bTemp = (a & b) << 1; a = aTemp; b = bTemp; } return a; } 3.两个数作减法运算 首先需要知道位运算的一个运算规律: ~n=-(n+1) ,比如:~3=-4 两个数作减法,如a-b可以转换成加法a+(-b),由上面的运算规律可知-b=~(b-1),因此a-b=a+(-b)=a+[~(b-1)],利用上一节的位运算实现两数相加即可。 int

Golang中位运算的详细理解

怎甘沉沦 提交于 2019-12-04 05:04:40
前言: 位运算可能在平常的编程中使用的并不多,但涉及到底层优化,一些算法及源码可能会经常遇见。今天就学习一下常用的位运算 一、常用的位运算: & 与 AND | 或 OR ^ 异或 XOR &^ 位清空 (AND NOT) << 左移 >> 右移 二、位运算的用法: 位运算都是在二进制的基础上进行运算的,所以在位运算之前要先将两个数转成二进制 1. & & 只有两个数都是 1 结果才为 1 例: var i uint8 = 20 var j uint8=15 求 i&j i 转成二进制为 0001 0100, j 转成二进制为 0000 1111 0001 0100 & 0000 1111 = 0000 0100 0000 0100 对应的十进制就是 4 2. | 或 两个数有一个是 1 结果就是 1 0001 0100 | 0000 1111 = 0001 1111 0001 1111 转成十进制就是 31 故 20 | 15 = 31 3. ^ ( 1 ) ^ 可以作为二元运算符,也可以作为一元运算符 ^ 作二元运算符就是异或,相同为 0 ,不相同为 1 如 1^1 =0, 0^0=0,1^0=1,0^1=1 0001 0100 ^ 0000 1111 = 0001 1011 故 20 ^ 15 =27 ( 2 ) ^ 作一元运算符表示是按位取反 ^0001 0100 =

位运算、移位运算符

只愿长相守 提交于 2019-12-04 05:04:12
一、位(bit)运算符: 位运算符 运算符含义 & 与(AND) | 或(OR) ^ 异或 ~ 取反 规则: 可以把1当做true ,0当做false 只有参与运算的两位都为1,&运算的结果才为1,否则就为0。 只有参加运算的两位都是0,| 运算的结果才是0,否则都是1。 只有参加运算的两位不同,^ 运算的结果才为1,否则就为0。 1、& 与运算 & 参见运算的两位数都为1,&运算符结果才为1,否则就为0。 6&3 00000000 00000000 00000000 00000110 –>6 00000000 00000000 00000000 00000011 –>3 00000000 00000000 00000000 00000010 & =2 2、| 或运算 | 参与运算的两位都为0,|运算的结果才为0,否则就为1。 00000000 00000000 00000000 00000110 –>6 00000000 00000000 00000000 00000011 –>3 00000000 00000000 00000000 00000111 | =7 3、^ 异或运算 ^只有参加运算的两位不同,^运算的结果才为1,否则就为0。 00000000 00000000 00000000 00000110 6 00000000 00000000 00000000

【位运算】位运算判断奇偶数、位运算求和、位运算求平均数、位运算求二进制1的个数

[亡魂溺海] 提交于 2019-12-04 05:02:52
位运算判断奇偶数: 2,4,6,8,10这样的数转化为二进制是10,100,1000,10000,将其减1后做与运算为0; x & (x-1) == 0 //偶数 x & (x-1) != 0 //奇数 位运算求平均数: int f(int x,int y) { return (x & y) + ((x ^ y) >> 1); } x & y //求相同位的与; x ^ y //取x和y的不同位 ; 右移相当于除2 ; 位运算求两数之和: int Add(int a,int b) { if(b == 0) return a; //没有进位的时候完成运算 int sum,carry; sum = a ^ b; //完成第一步没有进位的加法运算 carry = (a & b) << 1; //完成第二步进步并且左移运算 return Add(sum,carry); //进行递归,相加 } 位运算求二进制1的个数: int NumberOf1(int n) { int num = 0; while(n) { num++; n = (n-1) & n; //把二进制位中最右边的1变为0 } return num; } 利用标记位flag进行移动 int NumberOf1(int n) { int num = 0; int flag = 1; while(flag) { if((n &

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

冷暖自知 提交于 2019-12-03 19:44:11
接着上一篇博客,上一篇博客说明了HashMap的初始容量都是2的n次幂的形式存在的,而扩容也是2倍的原来的容量进行扩容,也就是扩容后的容量也是2的n次幂的形式存在的,下面就来说明一下为什么是2的n次幂的形式! 先来看一下源码,也就是向HashMap中添加元素,或者扩容时是怎么存放元素的。 第一个截图是向HashMap中添加元素putVal()方法的部分源码,可以看出,向集合中添加元素时,会使用(n - 1) & hash的计算方法来得出该元素在集合中的位置;而第二个截图是HashMap扩容时调用resize()方法中的部分源码,可以看出会新建一个tab,然后遍历旧的tab,将旧的元素进过e.hash & (newCap - 1)的计算添加进新的tab中,也就是(n - 1) & hash的计算方法,其中n是集合的容量,hash是添加的元素进过hash函数计算出来的hash值。 HashMap的容量为什么是2的n次幂,和这个(n - 1) & hash的计算方法有着千丝万缕的关系,符号&是按位与的计算,这是位运算,计算机能直接运算,特别高效,按位与&的计算方法是,只有当对应位置的数据都为1时,运算结果也为1,当HashMap的容量是2的n次幂时,(n-1)的2进制也就是1111111***111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列

位运算卷积

↘锁芯ラ 提交于 2019-12-03 17:15:54
定义 \[ \begin{aligned} mex(a,b)=\sum_{i=0}^{k-1}mex(a_i,b_i)3^i \end{aligned} \] 其中 \(a_i,b_i\) 表示 \(a,b\) 的三进制第 \(i\) 位,求 \[ \begin{aligned} c_k=\sum_{mex(i,j)=k}a_i,b_j \end{aligned} \] 我们先把柿子列出来 \[ \begin{aligned} &c_0 = a_1b_2 + a_2b_1 + a_1b_1 + a_2b_2\\ &c_1 = a_0b_0 + a_0b_2 + a_2b_0 \\ &c_2 = a_0b_1 + a_1b_0 \end{aligned} \] 然后把左边每一项都凑成可以表示成右边两个相同形式的积的形式,发现 \(3\) 位不够,得多加一位,而且还得额外搞一个 \(c_3\) \[ \begin{aligned} &c_0 = (a_1+a_2)(b_1+b_2) \\ &c_0 + c_1 + c_2 = (a_0 + a_1 + a_2)(b_0 + b_1 + b_2) \\ &c_3 = a_2b_2 \\ &c_1 + c_3 = (a_0 + a_2)(b_0 + b_2) \end{aligned} \] 这就是它的 \(FWT\) 了

你必须知道的基本位运算技巧(状压DP、搜索优化都会用到)

若如初见. 提交于 2019-12-03 13:22:01
一. 位操作基础 基本的位操作符有与、或、异或、取反、左移、右移这6种,它们的运算规则如下所示: 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两个位都为0时,结果才为0 ^ 异或 两个位相同为0,相异为1 ~ 取反 0变1,1变0 << 左移 各二进位全部左移若干位,高位丢弃,低位补0。1<<n等于2的n次方 >> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)。n>>2 等于 n/2的n次方 注意: 1. 在这6种操作符,只有~取反是单目操作符,其它5种都是双目操作符。 2. 位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。 二. 常用位操作小技巧 简单的位运算 1.’&’符号,x&y,会将两个十进制数在二进制下进行与运算,然后 返回其十进制下的值。例如3(11)&2(10)=2(10)。 2.’|’符号,x|y,会将两个十进制数在二进制下进行或运算,然后 返回其十进制下的值。例如3(11)|2(10)=3(11)。 3.’^’符号,x^y,会将两个十进制数在二进制下进行异或运算,然 后返回其十进制下的值。例如3(11)^2(10)=1(01)。 4.’<<’符号,左移操作,x<<2,将x在二进制下的每一位向左移动两位,最右边用0填充,x<

codeforces 2600+ Math标签刷题笔记

左心房为你撑大大i 提交于 2019-12-03 05:25:58
退役(?)前最后疯一把 997C 组合数学,容斥原理瞎搞,公式推导 622F 拉格朗日插值(比较裸)+ 观察优化 734F 位运算定理(fuck())+位运算瞎搞计算(check()) 439E 组合数学,容斥简单瞎搞 446C 二次剩余发现性质(5是1e9+9的二次剩余),线段树支持区间加等比数列及区间求和( \(a_l+=v^1,a_{l+1}+=v^2...\) ) 487C 寒假camp做过的(自己又忘了怎么做了,反省),智商题,构造,注意特判 912E 折半、二分答案、双指针check 258D 简单dp \(p_k[i][j]\) 表示 \(P_k(a_i>a_j)(k\) 是第 \(k\) 次更新后的情况 \()\) 959F 线性基裸题,求一个数有多少种子集的xor等于它。 906D 欧拉降幂裸题,注意 \(Mod(a,b)=a<b?a:a\%b+b\) . 来源: https://www.cnblogs.com/zhugezy/p/11779952.html

「JSOI2016」位运算

江枫思渺然 提交于 2019-12-03 05:06:26
题目描述 JYY 最近在研究位运算。他发现位运算中最有趣的就是异或 *(xor)* 运算。对于两个数的异或运算,JYY 发现了一个结论:两个数的异或值为 $0$ 当且仅当他们相等。于是 JYY 又开始思考,对于 $N$ 个数的异或值会有什么性质呢? JYY 想知道,如果在 $0$ 到 $R-1$ 的范围内,选出 $N$ 个不同的整数,并使得这 $N$ 个整数的异或值为 $0$,那么一共有多少种选择的方法呢?(选择的不同次序并不作重复统计,请参见样例) JYY 是一个计算机科学家,所以他脑海里的 $R$ 非常非常大。为了能够方便的表达,如果我们将 $R$ 写成一个 $01$ 串,那么 $R$ 是由一个较短的 $01$ 串 $S$ 重复 $K$ 次得到的。比如,若 $S=101,K=2$,那么 $R$ 的二进制表示则为 $101101$。由于计算的结果会非常大,JYY 只需要你告诉他选择的总数对 $10^9+7$ 取模的结果即可。 数据范围 $3\le N\le 7,1\le k\le 10^5,1\le |S|\le 50$ 题解 考虑到选出的数 $x_i$ 不同, $n$ 又很小,所以考虑状压, $f_{i,s}$ 表示前 $i$ 位,第 $j$ 位状态表示 $x_j$ 小于或等于 $x_{j+1}$ ,特殊的,我们设 $x_{n+1}=R$ 。