bitset

bitset专场

bitset 简介:

  1. 利用压位进行运算,降低了32个时间复杂度(讲32个01串变成一个整数)
  2. 对于图中两点的可达性求解有着极其暴力的压位方法

bitset中的

假设变量是 bitset<110> b

  1. b.set() 数字全部变成1
  2. b.set(x) 将x位上的数字变成1
  3. b.set(x, 0) 将x位上的数字变成0
  4. b.count() 求b中有多少1
  5. b.any() 有1就返回true,否则返回false
  6. b.none()有1就返回false,否则返回true
  7. b.reset()全部重置为0
  8. b.reset(x)将x位变成0
  9. b.flip()全部取反
  10. b.flip(x)将x位取反
  11. bitset支持位运算和判断的符号 (==,!=,&,|,^,~,>>,<<)

例题:

1826/problem/E

思路:

  1. 对于每一个城市,都有属于自己的方案,我们要做的就是在所有的方案中选择一种所有城市都可以接受的方案,并且方案要为最大值
  2. 前面的bitset的操作就是可以求出来所有的方案中所有城市都可以接受的方案,B[v] &= b 操作是v模特出现前哪些模特不能出现有一个城市中t模特不能在v模特出现前出现,那么t模特就一定不可达v模特
  3. 最终求得的是每个模特出场前,哪些模特可以出场(对于所有的城市)
  4. 最后对于路径直接dfs或者bfs动态规划求解

代码:

ll a[5010];
int r[510][5010];

bitset<5010> T;

void solve(){
	int n, m;
	cin >> m >> n;
	T.set();
	vector<bitset<5010>> B(n, T);
	for(int i = 0;i < n;i ++) cin >> a[i];
	for(int i = 0;i < m;i ++){
		for(int j = 0;j < n;j ++){
			cin >> r[i][j];
		}
		bitset<5010> b;
		vector<vector<int>> e(n + 1);
		for(int j = 0;j < n;j ++) e[r[i][j]].pb(j);
		for(int j = 1;j <= n;j ++){
			for(auto v : e[j]){
				B[v] &= b;
			}
			for(auto v : e[j]){
				b[v] = 1;
			}
		}
	}
	vector<int> deg(n, 0), e[n];
	queue<int> q;
	for(int i = 0;i < n;i ++){
		for(int j = 0;j < n;j ++){
			if(B[i].test(j)){
				e[j].pb(i);
				deg[i] ++;
			}
		}
	}
	for(int i = 0;i < n;i ++) {
		if(deg[i] == 0){
			q.push(i);
		}
	}
	vector<ll> dp(n, 0);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		dp[u] += a[u];
		for(auto v : e[u]){
			dp[v] = max(dp[v], dp[u]);
			if(-- deg[v] == 0){
				q.push(v);
			}
		}
	}
	cout << *max_element(dp.begin(), dp.end()) << '\n';
}

1795/problem/G

思路:

代码:

#include<bits/stdc++.h>
using namespace std;

int n, m;

void solve(){
	cin >> n >> m;
	vector<int> a(n);
	for(int i = 0;i < n;i ++) cin >> a[i];
	
	vector<int> adj[n];
	for(int i = 0;i < m;i ++){
		int u, v;
		cin >> u >> v;
		u --, v --;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	
	vector<int> q;
	for(int i = 0;i < n;i ++){
		a[i] = adj[i].size() - a[i];
		if(a[i] == 0) q.push_back(i);
	}
	for(int i = 0;i < n;i ++){
		for(auto t : adj[q[i]]){
			if(a[t] > 0 && -- a[t] == 0){
				q.push_back(t);
			}
		}
	}
	
	vector<int> pos(n, 0);
	for(int i = 0;i < n;i ++) pos[q[i]] = i;
	
	for(int i = 0;i < n;i ++){
		vector<int> nadj;
		for(auto t : adj[i]){
			if(pos[t] > pos[i]){
				nadj.push_back(t);
			}
		}
		swap(nadj, adj[i]);
	}
	
	long long ans = (long long) n * (n + 1) / 2;
	vector<bitset<8192>> bit(n);
	for(int i = 0;i < n;i += 8192){
		bit.assign(n, {});
		for(auto t : q){
			if(t >= i && t < i + 8192) bit[t][t - i] = 1;
			for(auto y : adj[t]){
				bit[y] |= bit[t];
			}
		}
		for(int j = 0;j < n;j ++){
			ans -= bit[j].count();
		}
	}
	
	cout << ans << endl;
	
}

int main(){
	int T;
	cin >> T;
	while(T --){
		solve();
	}
	return 0;
}
posted @   feuerwerk  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示