bitset是c++的一個類模板,聲明方法爲
#inlcude <bitset>
bitset<n>p; //此處的n必須爲常數
以下是它的一些成員函數的用法
b.any() |
b中是否存在置爲1的二進制位? |
b.none() |
b中不存在置爲1的二進制位嗎? |
b.count() |
b中置爲1的二進制位的個數 |
b.size() |
b中二進制位的個數 |
b[pos] |
訪問b中在pos處的二進制位 |
b.test(pos) |
b中在pos處的二進制位是否爲1? |
b.set() |
把b中所有二進制位都置爲1 |
b.set(pos) |
把b中在pos處的二進制位置爲1 |
b.reset() |
把b中所有二進制位都置爲0 |
b.reset(pos) |
把b中在pos處的二進制位置爲0 |
b.flip() |
把b中所有二進制位逐位取反 |
b.flip(pos) |
把b中在pos處的二進制位取反 |
b.to_ulong() |
用b中同樣的二進制位返回一個unsigned long值 |
os << b |
把b中的位集輸出到os流 |
最神奇的是它還可以使用位運算,這樣可以用來優化一些dp的狀態轉移,即位壓縮。
例如HDU5313
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <map>
#include <bitset>
using namespace std;
const int maxn = 20051;
vector<int>G[10001];
int id[10001];
int col[maxn];
bool vis[10001];
bitset<10001>dp;
struct node{
int a;
int b;
}tuan[10001];
void dfs(int u,int g){
id[u] = g;
vis[u] = 1;
for(int i = 0;i < G[u].size();i++){
int v = G[u][i];
if(!vis[v]){
dfs(v,g^1);
}
}
}
bool cmp(node a,node b){
return a.a-a.b>b.a-b.b;
}
int main()
{
int T,n,m;
//freopen("1004.txt","r",stdin);
cin>>T;
while(T--){
int nn = 0;
memset(id,0,sizeof(id));
memset(vis,0,sizeof(vis));
memset(col,0,sizeof(col));
scanf("%d%d",&n,&m);
int u,v;
for(int i = 0;i < m;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i = 1;i <= n;i++){
if(!vis[i]){
dfs(i,nn);
nn+=2;
}
}
for(int i = 1;i <= n;i++){
col[id[i]]++;
}
int cnt = 0;
for(int i = 0;i < nn;i += 2){
tuan[cnt].a = col[i];
tuan[cnt].b = col[i+1];
if(tuan[cnt].a < tuan[cnt].b) swap(tuan[cnt].a,tuan[cnt].b);
cnt++;
}
int a;
dp[tuan[0].a] = 1;
dp[tuan[0].b] = 1;
for(int i = 1;i < cnt;i++){
dp = (dp << tuan[i].a) | (dp << tuan[i].b);//狀態轉移
}
int maxx = 100100,k = n/2;
for(int i = 0;i < n;i++){
if(dp[i]){
if(maxx > abs(k-i)){
a = i;
maxx = abs(k-i);
}
}
}
int ans = a*(n-a)-m;
cout<<ans<<endl;
for(int i = 0;i <= n;i++) {G[i].clear(); }
dp.reset();
}
return 0;
}