异或

UVA-12716 GCD+异或运算性质+约数筛法

不想你离开。 提交于 2020-02-27 11:07:07
GCD XOR Description: 输入一个整数n,有多少对整数(a,b)满足 1≤b≤a≤n, g c d ( a , b ) = = a X O R b gcd(a,b)==a XOR b g c d ( a , b ) = = a X O R b 思路历程: ①暴力循环 时间复杂度 O(n^2 ),毫无疑问会超时。 ②考虑到(虽然自己一开始不知道) a X O R b = c , t h e n aXORb=c,then a X O R b = c , t h e n , a X O R c = b aXORc=b a X O R c = b 令c=gcd(a,b),或者 c 必然是a的约数,所以枚举a,c,用 a XOR c算出b,再检验 gcd(a,b)==c。 时间复杂度O(n logn logn ) ps:一开始还想着用 vector<int> facotr[] 去存储枚举的a的正约数集合,发现编译都通不过(数组太大了) 但是,这样还是TLE。还是得优化。 ③ g c d ( a , b ) ≤ a − b ≤ a X O R b a > b gcd(a,b)≤a-b≤aXORb\qquad a>b g c d ( a , b ) ≤ a − b ≤ a X O R b a > b 令 g c d ( a , b ) = a X O R b = c gcd(a

Java千问:Java位运算经典应用(二)

一笑奈何 提交于 2020-02-25 23:30:50
接上篇 三、不借助中间变量交换两个变量的值 通常情况下,我们要交换两个变量的值都按如下步骤操作: 这种操作方式不难理解,实现交换变量值的关键点就在于中间变量c。而现在的题目要求是不借助中间变量来交换a和b的值。如果不使用位运算的方式,同样可以做到不借助中间变量交换两个变量的值,其实现过程如下。 为了讲解方便,我们把最初a与b的值称之为原始a和原始b,3行代码就是3步操作: 第1步:把原始a与原始b相加的和存储到变量a中,变量b的值暂时没有发生变化。 第2步:用这个和减去原始b,再赋值到变量b中,经过这一步运算,变量b中就保存了原始a的值。 第3步:用原始a、b之和减去原始a的值,就得到原始b,并且把这个值保存到变量a中。 通过以上3步就实现了a、b两个变量在不借助中间变量的情况下进行值的交换。这种算法虽然没有借助中间变量,但有一个问题是如果a和b都是较大的数,在做第1步操作的时候就有可能出现两值相加的和超出int类型的最大值,产生溢出的现象,从而导致后面的运算全部出错。 而我们用位运算的方式实现交换,就不存在这个问题了。具体代码如下: 讲述这段代码之前,先回顾一个运算规律,那就是: a^b^b的运算结果等于a 。对此运算规律有疑义,请阅读《 Java千问:Java语言位运算符详解 》一文。为了表述方便,我们把a^b的操作称之为”用b对a加密”,之所以这么称呼

TwoDay 2020.02.24 运算符、循环 细节决定成败

前提是你 提交于 2020-02-25 15:49:13
比较运算符,运算完的结果必须是ture或者false 逻辑运算符用于连接,两个Boolean类型的表达式 &:运算规律:只有两边都为true,结果才是true |:运算规律:运算的两边只要有一个是true,结果肯定是true。只有两边都为false,结果是false ^(异或):符号两边结果如果相同 ,结果是false。 如果结果不同,结果是true。 &&:和&运算符结果是一样的。&&当左边为false时,右边不参与运算 ||:和|运算符结果是一样的。当左边为true时,右边不参与运算。 位运算符: ^(异或): 一个数异或同一个数两次,结果还是这个数。 <<:左移几位其实就是该数据乘以2的几次方。可以完成2的次幂运算。 >>:右移几位其实就是该数据除以2的几次幂。对于高位出现的空位,原来高位是什么就用什么补。 >>>:无符号右移:该数据进行右移时,高位出现的空位,无论原高位是什么,空位都用0补。 题:对两个整数变量的值进行交换(不需要第三方变量) 面试时:a=a^b; 开发时:int c; c=a; b=a^b; a=b; a=a^b; b=c; (使用第三方变量,因为阅读性强) 三元运算符:(条件表达式)?表达式1:表达式2; 如果结果为true,运算后的结果是表达式1 如果结果为false, 运算后的结果是表达式2 (就是if else 语句简写格式: 什么时候用? 当if

P2420 让我们异或吧

大兔子大兔子 提交于 2020-02-24 11:46:44
https://www.luogu.com.cn/problem/P2420 对于异或,就是将之前的求和的+号改为^ 即可 其他完全一样 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn=200000+10; 5 int n,m,r; 6 //见题意 7 int w[maxn],wt[maxn]; 8 //链式前向星数组,w[]、wt[]初始点权数组 9 int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn]; 10 //son[]重儿子编号,id[]新编号,fa[]父亲节点,cnt dfs_clock/dfs序,dep[]深度,siz[]子树大小,top[]当前链顶端节点 11 //查询答案 12 struct node 13 { 14 int v,w,nxt; 15 }G[maxn<<2]; int head[maxn]; int num; 16 struct tre 17 { 18 int l,r,lazy,sum; 19 int mx,mn; 20 }tree[maxn<<2]; 21 void add(int u,int v,int w) 22 { 23 G[++num

判定是否互为字符重排

亡梦爱人 提交于 2020-02-22 23:46:07
题意: 给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串 示例 1: 输入: s1 = “abc”, s2 = “bca” 输出: true 示例 2: 输入: s1 = “abc”, s2 = “bad” 输出: false 题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/check-permutation-lcci 核心思路: 0异或任何数结果为任何数,一个数异或它本身结果为0; a^a=0; a^b=c; a^c=b; b^c=0; 首先:当两个字符串长度相等时,它们才会有互为字符重排的可能 。 假设string1是“abcdef”,string2是“cdabf”,那么根据以上公式: 不管字符顺序如何,两个字符串内各个字符异或后,都是一个结果。 代码 class Solution { public boolean CheckPermutation(String s1, String s2) { if (s1.length() != s2.length()) return false; int sum = 0; char[] ch1=s1.toCharArray(); char[] ch2=s2.toCharArray(); for (int i = 0; i <

位运算

别来无恙 提交于 2020-02-20 10:23:11
1.位运算概述 从现代计算机中所有的数据二进制的形式存储在设备中。即0、1两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。 口说无凭,举一个简单的例子来看下CPU是如何进行计算的,比如这行代码: int a = 35; int b = 47; int c = a + b; 计算两个数的和,因为在计算机中都是以二进制来进行运算,所以上面我们所给的int变量会在机器内部先转换为二进制在进行相加: 35: 0 0 1 0 0 0 1 1 47: 0 0 1 0 1 1 1 1 ———————————————————— 82: 0 1 0 1 0 0 1 0 所以,相比在代码中直接使用(+、-、*、/)运算符,合理的运用位运算更能显著提高代码在机器上的执行效率。 2.位运算概览[td] 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两个位都为0时,结果才为0 ^ 异或 两个位相同为0,相异为1 ~ 取反 0变1,1变0 << 左移 各二进位全部左移若干位,高位丢弃,低位补0 >> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) 3.按位与运算符(&) # 定义:参加运算的两个数据,按二进制位进行“与”运算。 运算规则: 0&0=0 0

异或运算

别说谁变了你拦得住时间么 提交于 2020-02-19 11:41:23
性质 1、交换律 2、结合律(即(aXORb)XORc == aXOR(bXORc)) 3、对于任何数x,都有xXORx=0,xXOR0=x 4、自反性 A XOR B XOR B = A XOR 0 = A 异或运算最常见于多项式除法,不过它最重要的性质还是自反性:A XOR B XOR B = A,即对给定的数A,用同样的运算因子(B)作两次异或运算后仍得到A本身。这是一个神奇的性质,利用这个性质,可以获得许多有趣的应用。 例如,所有的程序教科书都会向初学者指出,要交换两个变量的值,必须要引入一个中间变量。但如果使用异或,就可以节约一个变量的存储空间: 设有A,B两个变量,存储的值分别为a,b,则以下三行表达式将互换他们的值 表达式 (值) : A=A XOR B (a XOR b) B=B XOR A (b XOR a XOR b = a) A=A XOR B (a XOR b XOR a = b) java中交换数据写法: int a = 10, b = 5 a = a ^ b; b = a ^ b; a = a ^ b; 来源: CSDN 作者: weixin_46224265 链接: https://blog.csdn.net/weixin_46224265/article/details/104389192

深入理解按位异或运算符

倾然丶 夕夏残阳落幕 提交于 2020-02-17 06:15:40
异或运算: 首先异或表示当两个数的二进制表示,进行异或运算时,当前位的两个二进制表示不同则为1相同则为0.该方法被广泛推广用来统计一个数的1的位数! 参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。 即:   0^0 = 0,   1^0 = 1,   0^1 = 1,   1^1 = 0 按位异或的3个特点: (1) 0^0=0,0^1=1 0异或任何数=任何数 (2) 1^0=1,1^1=0 1异或任何数-任何数取反 (3) 任何数异或自己=把自己置0 按位异或的几个常见用途: (1) 使某些特定的位翻转 例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。       10100001^00000110 = 10100111 (2) 实现两个值的交换,而不必使用临时变量。 例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:     a = a^b;   //a=10100111     b = b^a;   //b=10100001     a = a^b;   //a=00000110 位运算 位运算时把数字用二进制表示之后,对每一位上0或者1的运算。理解位运算的第一步是理解二进制。二进制是指数字的每一位都是0或者1.比如十进制的2转化为二进制之后就是10。

java:判断二进制数据中第n位是否为1

牧云@^-^@ 提交于 2020-02-17 02:19:53
一、进制转换 编程用十进制,十进制转换为二进制、八进制、十六进制 In [135]: bin(23) Out[135]: '0b10111' In [136]: oct(23) Out[136]: '0o27' In [137]: hex(23) Out[137]: '0x17' 也可以直接反向获取十进制 In [146]: 0b10111 Out[146]: 23 In [147]: 0o27 Out[147]: 23 In [148]: 0x17 Out[148]: 23 也可以用int函数来转换 In [149]: int('0b10111', 2) Out[149]: 23 In [150]: int('0o27', 8) Out[150]: 23 In [151]: int('0x17', 16) Out[151]: 23 二、位运算 按位异或的3个特点: (1) 0^0=0,0^1=1 0异或任何数=任何数 (2) 1^0=1,1^1=0 1异或任何数-任何数取反 (3) 任何数异或自己=把自己置0 按位异或的几个常见用途: (1) 使某些特定的位翻转 例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。       10100001^00000110 = 10100111 (2) 实现两个值的交换,而不必使用临时变量

线性基证明及使用

不羁的心 提交于 2020-02-13 13:54:32
线性基使用及证明 定义 线性基就是从一堆序列中,构造出一个序列,该序列通过异或组合可以组成原序列的任一一个序列(也就是线性代数所学的极大无关组的异或形式,也可以说是低配极大无关组,所以极大无关组满足的性质其都满足) 性质 性质1 由线性基可以异或出原序列的任一一个数 证明:由原序列求出一个线性基,设一个不在线性基的数为x,x不能被线性基异或得,则x可以插入线性基,则与线性基的定义矛盾,故得证 性质2 线性基中的数异或起来不能产生0 证明:设线性基里由 \(a_1...a_n\) 设 \(a_{b_1}\bigoplus a_{b_2}\bigoplus a_{b_3}=0\) 那么有 \(a_{b_1}\bigoplus a_{b_2} =a_{b_3}\) 所以只需要 \(a_{b_1} a_{b_2}\) 就可以表示原序列所有的数,所以线性基容量可以缩小,这与极大无关组的定义矛盾,得证 性质3 线性基的向量个数一定 证明 若同一组向量组存在两组线性基 \(a_{b_1} a_{b_2} a_{b_3}\) 和 \(a_{c_1} a_{c_2}\) 那么由线性基的定义,第二组线性基可以表示出第一组线性基的所有变量,那么由极大无关组定义,可以把第一组线性基 转换为第二组的线性组合,转化之后,组内相互异或仍然是线性基,所以第一组进行线性组合异或后,必然产生 \(a_{c_1} a_