
位运算
位运算的技巧、题解
csu_xiji
这个作者很懒,什么都没留下…
展开
-
力扣 29. 两数相除 位运算 模拟
https://leetcode-cn.com/problems/divide-two-integers/思路:很无聊的题目……商肯定可以用二进制表示,那么我们就可以模拟这个过程来求。class Solution {public: int divide(int dividend, int divisor) { if(dividend==INT_MIN&&divisor==-1) return INT_MAX; if(di原创 2021-10-13 01:01:33 · 143 阅读 · 0 评论 -
力扣 187. 重复的DNA序列 哈希 位运算
https://leetcode-cn.com/problems/repeated-dna-sequences/思路一:非常直观的方法,逐一取长度为10的子串,通过哈希计数即可。复杂度O(NL)O(NL)O(NL)。class Solution {public: vector<string> findRepeatedDnaSequences(string s) { vector<string> ans; const int LEN=10原创 2021-10-09 01:20:04 · 174 阅读 · 0 评论 -
力扣 1239. 串联字符串的最大长度 dfs 回溯 位运算
https://leetcode-cn.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/思路:dfs+回溯是比较容易看出来的。关键点在于重复字符的判断,如果每次都暴力遍历字符串计数的话,复杂度就太高了,我们可以使用二进制的思想,把一个字符串所含有的字符表示为一个二进制数,那么判断两个字符串是否有重复字符就很简单了,只需要把两个二进制数相与,看结果是否为0即可。class Solution {pub原创 2021-06-25 22:43:46 · 183 阅读 · 0 评论 -
力扣 477. 汉明距离总和 位运算
https://leetcode-cn.com/problems/total-hamming-distance/思路:分开计算二进制每一位的贡献即可,有两种方法,第一种方法先计算二进制每一位上1的个数,然后再遍历数组统计:class Solution {public: int totalHammingDistance(vector<int>& nums) { int cnt[31]={0}; for(const int& ele:n原创 2021-06-07 15:08:26 · 89 阅读 · 0 评论 -
力扣 461. 汉明距离 位运算 分治
https://leetcode-cn.com/problems/hamming-distance/思路:相当于统计x⨁yx\bigoplus yx⨁y结果中1的数量。那么可以使用内置函数计算:class Solution {public: int hammingDistance(int x, int y) { return __builtin_popcount(x^y); }};或者使用位运算计算,其中x&(x−1)x\&(x-1)x&原创 2021-06-07 14:45:38 · 124 阅读 · 0 评论 -
力扣 1442. 形成两个异或相等数组的三元组数目 异或 哈希
思路:设S0=0,Si=a0⨁a1⨁……⨁ai−1S_0=0,S_i=a_0\bigoplus a_1\bigoplus……\bigoplus a_{i-1}S0=0,Si=a0⨁a1⨁……⨁ai−1,由异或性质可知,数组arrarrarr的[i,j−1][i,j-1][i,j−1]的异或和等于Sj⨁SiS_j \bigoplus S_iSj⨁Si,那么由题目的a=ba=ba=b可以化简得到Si=Sk+1S_i=S_{k+1}Si=Sk+1,此时jjj有k+1−ik+1-ik+1−i种选.原创 2021-05-18 21:07:13 · 128 阅读 · 0 评论 -
力扣 1734. 解码异或后的排列 位运算(异或)
https://leetcode-cn.com/problems/decode-xored-permutation/思路:由于原序列是nnn个正整数的排列,且nnn为奇数,那么我们可以得到原序列的异或和v1=1⨁2⨁...nv_1=1 \bigoplus 2 \bigoplus ...nv1=1⨁2⨁...n,然后再取输入序列的奇数位置或偶数位置的异或和设为v2v_2v2,显然v1⨁v2v_1 \bigoplus v_2v1⨁v2就等于原序列的a0a_0a0或ana_nan,那么问题就解决了原创 2021-05-13 14:51:24 · 128 阅读 · 0 评论 -
力扣 1723. 完成所有工作的最短时间 二分+回溯+剪枝/状压dp
https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/思路一:显然最大工作时间满足单调性,所以可以用二分来写。但是每次checkcheckcheck我们只能暴力递归,这样会超时……所以要加上一些剪枝操作……这里简单说一下吧,任务要从耗时多的开始分配,如果第一次分配都没有找到可行解,那么一定没有可行解(该次递归下),如果最优分配没有可行解,那么一定没有可行解(该次递归下)。class Solution {public原创 2021-05-08 17:35:00 · 493 阅读 · 0 评论 -
力扣 90. 子集 II 位运算 回溯
https://leetcode-cn.com/problems/subsets-ii/思路:有重复元素,所以枚举的时候要注意了。我们先对nums从小到大排序,假设当前选择了第x个元素,如果我们没有选择第x-1个元素但是这两个元素的值相等,那么一定会有重复的子集,直接跳过这种情况就行了。class Solution {public: vector<vector<int>> subsetsWithDup(vector<int>& nums) {原创 2021-03-31 22:34:35 · 152 阅读 · 0 评论 -
力扣 78. 子集 位运算 回溯
https://leetcode-cn.com/problems/subsets/思路:因为nums中没有重复元素,所以通过位运算直接枚举即可,当然回溯法也可以。class Solution {public: vector<vector<int>> subsets(vector<int>& nums) { int n=nums.size(),times=1<<n; vector<vector<原创 2021-03-31 22:29:23 · 160 阅读 · 0 评论 -
力扣 190. 颠倒二进制位 位运算 分治
https://leetcode-cn.com/problems/reverse-bits/思路:逐位置颠倒的算法就不说了。说一下分治算法:将其均分成左右两部分,对每部分递归执行翻转操作,然后将左半部分拼在右半部分的后面,即完成了翻转。利用位运算的性质可以自底向上进行这个过程:2位一组,每一组的前1位和后1位互换。4位一组,每一组的前2位和后2位互换。8位一组,每一组的前4位和后4位互换。16位一组,每一组的前8位和后8位互换。32位一组,每一组的前16位和后16位互换。class原创 2021-03-29 01:26:25 · 284 阅读 · 3 评论 -
力扣 191. 位1的个数 位运算
https://leetcode-cn.com/problems/number-of-1-bits/思路一:利用C++的内置函数。class Solution {public: int hammingWeight(uint32_t n) { return __builtin_popcount(n); }};思路二:利用位运算性质,每次把末尾的1去掉。class Solution {public: int hammingWeight(uint32_t原创 2021-03-22 14:56:42 · 137 阅读 · 0 评论 -
力扣 705. 设计哈希集合 哈希(链式地址法) 位运算实现哈希
https://leetcode-cn.com/problems/design-hashset/思路一:朴实无华且枯燥的链地址法,通过vector、forward_listvector、forward\_listvector、forward_list实现(后者是一个单向链表)。class MyHashSet {public: /** Initialize your data structure here. */ const int num=2333; vector<fo原创 2021-03-13 03:02:33 · 289 阅读 · 0 评论 -
PIPIOJ 1489: PIPI的位运算问题Ⅴ 位运算 构造
http://pipioj.online/problem.php?id=1489思路:由或运算和加法的性质可知,x+y>=x∣yx+y>=x|yx+y>=x∣y,那么当b>=ab>=ab>=a时我们需要进一步的推断,由于加法存在进位情况,我们用一个布尔值jwjwjw来标记是否有进位操作发生,从低到高考虑a、ba、ba、b二进制的每一位:ai=0,bi=0a_i=0,b_i=0ai=0,bi=0,则只能令xi=yi=0x_i=y_i=0xi=yi=0,若jw原创 2021-03-09 15:48:54 · 144 阅读 · 0 评论 -
PIPIOJ 1485: PIPI的位运算问题Ⅳ 位运算
http://pipioj.online/problem.php?id=1485思路:核心思想就是把输入转为二进制表示,然后分别考虑每一位的贡献。我们可以用sumisum_isumi表示输入数据流中二进制表示第iii位1的总和,那么在读入第i个数据时,此时sumsumsum数组记录的就是前i-1个数据的信息,那么单独考虑第i个数据的每一位,我们可以轻松的得到前i-1个数据中在这一位上和它相等或不等的个数,根据异或性质累加即可。#include<bits/stdc++.h>#define原创 2021-03-09 14:44:51 · 317 阅读 · 0 评论 -
PIPIOJ 1440: PIPI的位运算问题Ⅲ 位运算 贪心
http://pipioj.online/problem.php?id=1440思路:依次读入nnn个数字,设tobtobtob为一函数,它接受一个整型参数xxx,返回xxx的二进制表示(数组形式),因为ai<=1018a_i<=10^{18}ai<=1018且260>10182^{60}>10^{18}260>1018,我们可以通过以下方式计算出数组sumsumsum:sumi=∑j=0ntob(aj)[i]sum_i=\sum_{j=0}^ntob(a_j)原创 2021-03-09 01:31:52 · 145 阅读 · 0 评论 -
PIPIOJ 1439: PIPI的位运算问题Ⅱ 位运算 异或和
http://pipioj.online/problem.php?id=1439思路:如果我们能够快速计算出[0,n][0,n][0,n]内所有数的二进制第iii位(假设从低位开始,下标从1开始)上111的总和,那么依据前缀和的性质就可以在O(1)O(1)O(1)时间内得到[L,R][L,R][L,R]内所有数的二进制第iii位上111的总和,依据异或的性质我们知道,如果总和是奇数,那么这一位为111否则为000。那么如何快速计算总和呢?我们写下前八个数的二进制表示:000、001、010、011、10原创 2021-03-07 02:13:47 · 248 阅读 · 0 评论 -
PIPIOJ 1436: PIPI的位运算问题Ⅰ 位运算
http://pipioj.online/problem.php?id=1436思路:将L、RL、RL、R转换为二进制表示,从高位开始枚举,显然每一位有四种情况(其实只有三种情况,因为R>=L),当Ri=1R_i=1Ri=1且Li=0L_i=0Li=0时,我们可以把所有的RjR_jRj设为000,LjL_jLj设为111(j>i),这就是最优解。#include<bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace原创 2021-03-06 21:55:13 · 216 阅读 · 0 评论 -
codeforces 1300C Anu Has a Function 二进制 位运算
https://vjudge.net/problem/CodeForces-1300C题目大意:定义函数f(x,y)=(x∣y)−yf(x,y)=(x|y)-yf(x,y)=(x∣y)−y。给一个数组a[1……n]a[1……n]a[1……n],那么该数组的价值定义为f(f(…f(f(a1,a2),a3),…an−1),an)f(f(…f(f(a_1,a_2),a_3),…a_{n-1}),a_n...原创 2020-02-11 12:31:37 · 205 阅读 · 0 评论 -
codeforces 1332D Walk on Matrix 位运算+构造
https://vjudge.net/problem/CodeForces-1332D题目大意:假设有一个n∗mn*mn∗m的矩阵,初始位置在(1,1)(1,1)(1,1),score1=a11score_1=a_{11}score1=a11,每次只能向右或向下走,假设走到了位置(x,y)(x,y)(x,y),那么分数变为scorei=scorei−1&axyscore_i=sc...原创 2020-04-01 18:39:06 · 284 阅读 · 0 评论 -
力扣 645. 错误的集合 位运算
https://leetcode-cn.com/problems/set-mismatch/思路:做法很多,只考虑空间O(1)O(1)O(1)的方法。设答案为a、ba、ba、b,数组的异或和为sumsumsum,再对所有的1<=i<=n1<=i<=n1<=i<=n做一遍sum xor isum\ xor\ isum xor&nb...原创 2020-04-24 17:21:07 · 320 阅读 · 0 评论 -
力扣 1290. 二进制链表转整数 链表 位运算
https://leetcode-cn.com/problems/convert-binary-number-in-a-linked-list-to-integer//** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Soluti原创 2020-08-03 17:02:30 · 152 阅读 · 0 评论 -
力扣 1178. 猜字谜 位运算 思维
https://leetcode-cn.com/problems/number-of-valid-words-for-each-puzzle/思路:看完题目会发现关键点是一个单词中出现的字符种类,和个数没有关系,那么我们可以用位运算表示某个单词含有的字符种类。具体做法是,如果它含有小写字母xxx,我们就可以把它二进制表示的第x−′a′x-'a'x−′a′位置为111。这样就将字符串变成了整数,接下来构建一个哈希表,记录某个整数所对应的字符串个数。对于每个puzzlepuzzlepuzzle我们可以得到它原创 2021-02-28 14:21:36 · 209 阅读 · 0 评论 -
力扣 338. 比特位计数 位运算 dp
https://leetcode-cn.com/problems/counting-bits/思路一:一个数可以通过2的幂次的和来表示出来,那么假设当前增加的数为addaddadd,通过枚举所有大于addaddadd且小于等于numnumnum的2的幂次就可以递推出新的数。class Solution {public: vector<int> countBits(int num) { vector<int> ans(num+1); in原创 2021-03-03 20:18:28 · 229 阅读 · 1 评论