位运算基础知识

基础知识 

可以把它想成消消乐,两个相同就消掉了。

左移空出来的就补0

右移也是空的补0

技巧

z & -z 实际上是将 z 与 -z 进行按位与操作。这个操作的结果是保留 z 与 -z 二进制表示中共同为 1 的位,而将其他位设为 0。因为 -z 中只有最右边的 1 保持不变,其他位都会被 z 中的相应位设为 0,所以 z & -z 的结果就是 z 二进制表示中最低位的 1 所代表的值。

从右往左数第一个1(最低位)

蓝桥1331

import os
import sys

# 请在此输入您的代码
x = int(input())
ans = 0
for i in range(32):
  if (x >> i) & 1 == 1:
    ans += 1
print(ans)

蓝桥17021

暴力

def lowbit(z):
    return z & -z

def count_combinable_pairs(nums):
    count = 0
    # 检查每对数字是否满足条件
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if lowbit(nums[i] + nums[j]) == nums[i] + nums[j]:
                count += 1

    return count

# 读取输入
N = int(input())
nums = list(map(int, input().split()))

# 计算可结合的元素对的数量并输出结果
print(count_combinable_pairs(nums))

正解

from collections import Counter

n = int(input())
a = list(map(int, input().split()))

# 存储2的次幂 [2, 2 ^ 31]
power = []
x = 2
for i in range(1, 32):
    power.append(x)
    x = x * 2

# 储存a[j]出现次数
b = Counter()
ans = 0

# 枚举每个数a[i]
for x in a:
    # 优化第二重循环:遍历2的次幂
    for y in power:
        if y - x in b: 前面能有跟他配对的,就加上这个数出现的频率。
            ans += b[y - x]
    b[x] += 1
print(ans)

蓝桥3691

 

#区间或运算(思维,前缀和)
import sys
#001 010 011 100 101
#第零位: [1,0,1,0,1]
#第一位: [0,1,1,0,0]
#第二位: [0,0,0,1,1]
from itertools import accumulate
import sys#加速
input=sys.stdin.readline
n,q=map(int,input().split())
a=list(map(int,input().split()))#第零位到第三十位的前缀和
a_bit=[]
for i in range(32):
    #求a数组中每个数字的第i位是0还是1
    now=[]
    for x in a:
        now.append((x>>i)&1)
    a_bit.append(list(accumulate(now)))
for _ in range(q):
    l,r=map(int,input().split())
    l,r=l-1,r-1
    ans=0
    for i in range(32):
        #每一位单独考虑,对于第i位而言,只需要判断[l,r]的和是否大于0
        if l==0:
            t=a_bit[i][r]
        else:
            t=a_bit[i][r]-a_bit[i][l-1]
        if t>0:
            ans+=(1<<i)
    print(ans)

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值