位运算
位运符号优先级
| 加减 | 移位 | 比较大小 | 与 | 异或 | 或 |
|---|---|---|---|---|---|
| +,- | << >> | < > == != | & | ^ | | |
优先级
高————————————>低
二进制状态压缩
取出整数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;
}
这道题主要考察异或运算
#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);
}

浙公网安备 33010602011771号