返回顶部

位运算

位运符号优先级

加减 移位 比较大小 异或
+,- << >> < > == != & ^ |

优先级

高————————————>低

二进制状态压缩

取出整数n在二进制表示下的第k位
(n>>k)&1
取出整数n在二进制表示下的前k位
n&((1<<k)-1)
取出整数n在二进制表示下第k位取反
n^(1<<k)
取出整数n在二进制表示下第k位赋值1
n|(1<<k)
取出整数n在二进制表示下第k位赋值0
n&(~(1<<k))

lowbit

int lowbit(int x){
return x&-x;
}

c++内置函数

	
	__builtin_ctz(unsigned int x);
	__builtin_ctzll(unsigned long long x);
	返回x的二进制表示下最低位的1后边有多少个0
	__builtin_popcount();
	__builtin_popcountll();
	返回x的二进制表示下有多少位为1

bitset

头文件
#include<bitset>

Constructors 创建新bitsets
Operators 比较和赋值bitsets
any() 如果有任何一个位被设置就返回true
count() 返回被设置的位的个数
flip() 反转bits中的位
none() 如果没有位被设置则返回true
reset() 清空所有位
set() 设置位
size() 返回可以容纳的位的个数
test() 返回指定位的状态
to_string() 返回bitset的字符串表示
to_ulong() 返回bitset的整数表示

例题

可达性统计

#include<bits/stdc++.h>
using namespace std;
const int N = 3e4+10,M = N;
int h[N], e[M], ne[M], idx;
void add(int a, int b)  // 添加一条边a->b
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
bitset<N>f[N];
queue<int>q;
int d[N];
vector<int>stk;//记录拓扑序
bool st[N];
void bfs(){
    while(q.size()){
        int t = q.front();
        stk.push_back(t);
        q.pop();
        for(int i=h[t];~i;i=ne[i]){
            int j = e[i];
            if(st[j])continue;
            if(--d[j]==0)
            q.push(j);
        }
    }
}
int main(){
    int n,m;
    scanf("%d%d", &n, &m);
    memset(h,-1,sizeof h);
    while (m -- ){
        int x,y;
        scanf("%d %d",&x,&y);
        add(x,y);
        d[y]++;
    }
    for(int i=1;i<=n;i++)
        if(!d[i])q.push(i);
    bfs();
    for(int j=n-1;j>=0;j--){
        int u = stk[j];
        for(int i=h[u];~i;i=ne[i]){
            int j=e[i];
            f[u]|=f[j];
        }
        f[u][u] = 1;
    }
    for(int i=1;i<=n;i++)
        cout<<f[i].count()<<endl;
    return 0;
    
}

P1469 找筷子

这道题主要考察异或运算

#include<cstdio>
int x,n,ans;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&x),ans^=x;
    printf("%d\n",ans);
}
posted @ 2023-11-17 16:31  supperwriter  阅读(49)  评论(0)    收藏  举报