bitset优化例题

news2025/4/16 13:55:50

1. bitset 优化背包 

https://loj.ac/p/515

题意:

给 n 个 <= n 的数,每个数有取值范围 a[ i ] - b[ i ],令 x 为 n 个数的平方和,求能构成的 x 的个数

样例:

5
1 2
2 3
3 4
4 5
5 6

 26

思路:

背包dp,dp[ i ][ j ] 表示用前 i 个数能不能组成 j ,用 bitset 优化

用一个 bitset dp 维护 当前的数 可以组成哪几个 x ,用 bitset tmp 维护 当前的状态 可以转移到哪几个状态,滚动优化空间,复杂度为O(n^5 / 64)

代码:

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

const int N=1e6+5;
bitset<N>dp,tmp;

void solve(){
    int n;
    cin>>n;
    dp.set(0);    //初始化
    for(int i=1;i<=n;i++){
        int a,b;
        cin>>a>>b;
        tmp.reset();
        for(int j=a;j<=b;j++){
            tmp|=(dp<<(j*j));
        }
        dp=tmp;
    }
    cout<<dp.count()<<endl;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

2. bitset 优化图上问题(可达性统计问题)

https://www.acwing.com/problem/content/166/

题意:

给一个 n 个点,m 条边的 有向无环图,求每个点能到达的 点的个数

样例:

10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9

1
6
3
3
2
1
1
1
1

思路:

反向建图,然后利用 拓扑排序,进行图上dp,dp[ i ][ j ]表示从点 i 出发能不能到达 点 j ,用 bitset优化,若存在 u - > v 的边,则 dp[ u ] | = dp[ v ]

复杂度为 O(n^2 / 64)

代码:

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

const int N=3e4+5;

int head[N],cntt=0;
struct Edge{
    int to,next,val;
}edge[N];
void add(int u,int v,int x){
    edge[++cntt].to=v;
    edge[cntt].val=x;
    edge[cntt].next=head[u];
    head[u]=cntt;
}

int deg[N];
bitset<N>dp[N];
void solve(){
    int n,m;
    cin>>n>>m;
    while(m--){
        int u,v;
        cin>>u>>v;
        add(v,u,1);
        deg[u]++;
    }
    queue<int>q;
    for(int i=1;i<=n;i++){
        dp[i][i]=1;
        if(deg[i]==0)q.push(i);
    }
    while(!q.empty()){
        int tmp=q.front();
        q.pop();
        for(int i=head[tmp];i;i=edge[i].next){
            int y=edge[i].to;
            dp[y]|=dp[tmp];
            deg[y]--;
            if(deg[y]==0)q.push(y);
        }
    }
    for(int i=1;i<=n;i++)cout<<dp[i].count()<<endl;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

3. bitset 优化枚举

https://codeforces.com/contest/333/problem/E

题意:

给 n 个点,找 3 个点,以这三个点为圆心,画 3 个半径相同互不相交的圆,求最大的半径

可以转化为,给 n 个点,找出 最小边最大 的三角形,求最大的最小边

思路:

将所有边按边长降序排列,依次枚举当前边作为最小边,然后枚举其它点,若存在某点 和 当前的边的两个点都已经连有边(即存在以当前边为最小边的三角形),则找到答案,否则连上这条边

直接枚举的复杂度是 O ( n^3 ) ,可以用一个标记数组 vis [ i ] [ j ] 表示有没有 i - j 的边,用 bitset 优化这个数组,每次 对于 x-y 的边,通过 vis[x] & vis[y] 可以在 O ( n/64 ) 时间内快速判断有没有符合条件的点,在 O ( n^3/64 ) 复杂度下通过本题

样例:

7
2 -3
-2 -3
3 0
-3 -1
1 -2
2 -2
-1 0

1.58113883008418980000 

代码:

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

const int N=3e3+5;

double x[N],y[N];
double length(int a,int b){
    return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
struct node{
    int x,y;
    double len;
    bool operator<(const node a)const{
        return len>a.len;
    }
};
vector<node>edge;
bitset<N>vis[N];
void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            edge.push_back((node){i,j,length(i,j)});
        }
    }
    sort(edge.begin(),edge.end());
    for(auto e:edge){
        int x=e.x,y=e.y;
        double len=e.len;
        if((vis[x]&vis[y]).any()){
            cout<<fixed<<setprecision(8)<<len/2<<endl;
            return;
        }
        vis[x].set(y);
        vis[y].set(x);
    }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

4. bitset 优化 01 矩阵乘法

http://acm.hdu.edu.cn/showproblem.php?pid=7293

题意:

给一张无向图,求图中有多少个 下图形状的子图

思路:

对无向图建邻接矩阵,对邻接矩阵进行平方,新矩阵 a[ i ] [ j ] 表示 从 i 点到 j 点 长为2的路径个数,枚举子图中 度为6和4的两个点,通过组合数计算子图数量即可,复杂度为 O(n^3)

利用 bitset 优化,01矩阵的平方 可以通过 b [ i ] [ j ] = ( r [ i ] & c [ j ] ) . count () 计算,由于无向图的邻接矩阵是 对称矩阵,所以直接用 ( vis [ i ] & vis [ j ] ) . count () 表示矩阵平方,复杂度为 O(n^3/64)

样例:

1

8 10

1 2

1 3

1 4

1 5

1 6

1 7

8 4

8 5

8 6

8 7

1

代码:

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

inline int read(){  //快读快写
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x;
}
inline void write(int x){
    if(x>9)write(x/10);
    putchar(x%10+'0');
}

const int N=1005;
const int mod=1e9+7;

int fact[N],inv[N];        //O(1)求组合数
inline int qpow(int a,int b){
    int ans=1;
    while(b>0){
        if(b&1)
        ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
void Cinit(){
    fact[0]=1,inv[0]=1;
    for(int i=1;i<=N-1;i++){
        fact[i]=fact[i-1]*i%mod;
    }
    inv[N-1]=qpow(fact[N-1],mod-2)%mod;
    for(int i=N-2;i>=1;i--){
        inv[i]=inv[i+1]*(i+1)%mod;
    }
}
inline int C(int a,int b){
    if(a<0||b<0||a<b)return 0;
    return fact[a]*inv[a-b]%mod*inv[b]%mod;
}

bitset<N>vis[N];
void solve(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++)vis[i].reset();
    while(m--){
        int u=read(),v=read();
        vis[u].set(v);
        vis[v].set(u);
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int cnt1=vis[i].count(),cnt2=vis[j].count();
            int cnt=(vis[i]&vis[j]).count();    // 矩阵乘
            if(vis[i][j]){      //不能选两点直接相连的边
                cnt1--,cnt2--;
            }
            ans+=C(cnt1-4,2)*C(cnt,4);
            ans%=mod;
            ans+=C(cnt2-4,2)*C(cnt,4);
            ans%=mod;
        }
    }
    write(ans);
    putchar('\n');
    return;
}


signed main(){
    Cinit();
    int T=read();
    while(T--){
        solve();
    }
    return 0;
}

5. bitset 优化 floyd

https://www.luogu.com.cn/problem/P4306

题意:

给一张有向图,求每个点能到达的点的个数的和

样例:

3
010
001
100

思路:

考虑 floyd 上 dp,dp [ i ] [ j ] 表示点 i 能到达点 j ,转移方程为 dp[ i ][ j ] |= (dp[ i ][ k ] &dp[ k ][ j ] )

用 bitset 优化转移,复杂度为 O(n^3/64) 

代码:

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

const int N=2e3+5;
bitset<N>dp[N];
void solve(){
    int n;
    cin>>n;
    vector<string>s(n+1);
    for(int i=1;i<=n;i++){
        cin>>s[i];
        s[i]=' '+s[i];
        dp[i].set(i);
        for(int j=1;j<=n;j++){
            if(s[i][j]=='1'){
                dp[i].set(j);
            }
        }
    }
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            if(dp[i][k]){
                dp[i]|=dp[k];
            }
//            dp[i][j]|=dp[i][k]|dp[k][j];
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)ans+=dp[i].count();
    cout<<ans<<endl;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/813152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VUE之VueRouter页面跳转

参考资料&#xff1a; 参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用&#xff0c;跨域问题&#xff0c;拦截器添加Token Vue Router官网 Vue Router说明&#xff1a; 说明&#xf…

SpringBoot接手JSP项目--【JSB项目实战】

SpringBoot系列文章目录 SpringBoot知识范围-学习步骤【JSB系列之000】 文章目录 SpringBoot系列文章目录[TOC](文章目录) SpringBoot技术很多很多工作之初&#xff0c;面临JSP的老项目我要怎么办环境及工具&#xff1a;项目里可能要用到的技术JSPjstl其它的必要知识 上代码WE…

数据结构:第六章 图

文章目录 一、图的基本概念1.1定义1.2有向图、无向图1.3顶点的度、入度、出度1.4顶点-顶点关系的描述1.5子图和生成子图1.6连通分量1.6强连通分量1.7生成树1.8生成森林1.9边的权、带权图/网1.10几种特殊的图1.11小结 二、图的存储及基本操作2.1邻接矩阵法2.1.1邻接矩阵存储不带…

29_互联网(The Internet)(IP数据包;UDP;TCP;DNS;OSI)

上篇介绍了计算机网络的基础知识&#xff0c;也提到互联网&#xff08;The Internet&#xff09;&#xff0c;本篇将会详细介绍互联网&#xff08;The Internet&#xff09;。 文章目录 1. 互联网&#xff08;The Internet&#xff09;组成及数据包传输过程2. IP 数据包的不足3…

【Spring Boot 源码学习】走近 AutoConfigurationImportSelector

AutoConfigurationImportSelector 源码解析 引言主要内容1. ImportSelector 接口2. DeferredImportSelector 接口3. AutoConfigurationImportSelector 功能概述 总结 引言 上篇博文我们了解了 EnableAutoConfiguration 注解&#xff0c;其中真正实现自动配置功能的核心实现者 …

手把手一起实现Visual Studio 2022本地工程提交(和克隆)Gitee

1、VS2022本地工程提交Gitee 登录Gitee&#xff0c;创建空仓库&#xff0c;如图&#xff1a; 新建仓库&#xff1a; 打开Visual Studio 2022创建的工程&#xff0c;点击创建Git存储库&#xff1a; 复制Gitee仓库URL&#xff1a; 将URL填入&#xff0c;点击创建并推送&#xff…

计算机基本硬件的内部结构

1.早期冯诺依曼机结构 世界上第一台计算机ENIAC是使用手动接线来控制计算&#xff0c;十分麻烦。 冯诺依曼提出“存储程序”的概念&#xff0c;是指将指令以二进制代码的形式事先输入计算机的主存储器&#xff08;内存&#xff09;&#xff0c;然后按照其在存储器中的首地址执…

【递归、搜索与回溯算法练习】day1

文章目录 一、面试题 08.06. 汉诺塔问题1.题目简介2.解题思路3.代码4.运行结果 二、21. 合并两个有序链表1.题目简介2.解题思路3.代码4.运行结果 三、206. 反转链表1.题目简介2.解题思路3.代码4.运行结果 总结 一、面试题 08.06. 汉诺塔问题 1.题目简介 面试题 08.06. 汉诺塔…

玩转LaTeX(二)【特殊字符、插图设置、表格、浮动体】

特殊字符&#xff1a; 导言区&#xff1a;&#xff08;添加几个宏包&#xff09; \usepackage{xltxtra} %\XeLaTeX(提供了针对XeTeX的改进并且加入了XeTeX的LOGO)\usepackage{texnames} %LOGO\usepackage{mflogo}\usepackage{ctex} 正文区&#xff1a; \begin{document}…

vue拖拽改变宽度

1.封装组件ResizeBox.vue <template><div ref"resize" class"resize"><div ref"resizeHandle" class"handle-resize" /><slot /></div> </template> <script> export default {name: Resi…

【八】mybatis 日志模块设计

mybatis 日志模块设计 简介&#xff1a;闲来无事阅读一下mybatis的日志模块设计&#xff0c;学习一下优秀开源框架的设计思路&#xff0c;提升自己的编码能力 模块设计 在Mybatis内部定义了4个级别&#xff1a;Error:错误 、warn:警告、debug:调试、trance&#xff0c;日志优…

C++STL序列式容器——vector容器详解

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.vector容器基本概念二.vector常用操作①vector构造函数②特性操作③元素操作④赋值操作⑤交换操作⑥比较操作⑦插入和删除操作 一.vector容器基…

MATLAB编程实践12、13

生命游戏 游戏的宇宙是无限可扩展的二维矩形网格&#xff0c;群体是那些标注为存活的网格的集合。群体可以依照称为代的离散时间步距进化。在每一步中&#xff0c;每个网格的命运由它周围最近的8个网格邻居的活度决定&#xff0c;规则如下&#xff1a; 如果一个存活的网格有两个…

想阻止BOT攻击?一起聚焦灵活有效的F5解决方案

伴随着突如其来的数字创新&#xff0c;使潜在的欺诈无处不在。现在&#xff0c;帮我们查找机票交易、位置理想的演唱会座位的 BOT技术正在为网络犯罪分子所利用。权威数据表示&#xff0c;在过去5年&#xff0c;撞库攻击已成为造成经济损失的最大原因之一&#xff0c;几乎每个企…

小研究 - 基于解析树的 Java Web 灰盒模糊测试(二)

由于 Java Web 应用业务场景复杂, 且对输入数据的结构有效性要求较高, 现有的测试方法和工具在测试Java Web 时存在测试用例的有效率较低的问题. 为了解决上述问题, 本文提出了基于解析树的 Java Web 应用灰盒模糊测试方法. 首先为 Java Web 应用程序的输入数据包进行语法建模创…

前端技术周刊 2023-07-30:Promise.withResolvers 进入 Stage3

项目地址&#xff1a;olivewind/weekly[1] 微信公众号&#xff1a;依赖注入 发布时间&#xff1a;2023.07.30 本周内容&#xff1a;资讯x2、开源x8、文章x4 动态 Promise.withResolvers 进入 Stage3 某些情况下需要在 Promise 外部获取 resolve 和 reject 句柄&#xff0c;我们…

【云原生】一文学会Docker存储所有特性

目录 1.Volumes 1.Volumes使用场景 2.持久将资源存放 3. 只读挂载 2.Bind mount Bind mounts使用场景 3.tmpfs mounts使用场景 4.Bind mounts和Volumes行为上的差异 5.docker file将存储内置到镜像中 6.volumes管理 1.查看存储卷 2.删除存储卷 3.查看存储卷的详细信息…

RWEQ模型参量提取

土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一&#xff0c;土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风蚀荒漠化面积达160.74104km2&#xff0c;占国土总面积的16.7%&#xff0c;严重影响这些地区的资源开发和社会经…

机器学习深度学习——Dropout

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——权重衰减 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助 Drop…

【MTI 6.S081 Lab】traps

【MTI 6.S081 Lab】traps RISC-V assembly (easy)Backtrace (moderate)实验任务Hints解决方案backtracesys_sleep Alarm (hard)实验任务test0: invoke handlerHint test1()/test2()/test3(): resume interrupted codeHints 解决方案trap.c中的时钟中断处理程序sys_sigalarmsys_…