• bitset用法和ch2101可达性统计


    我又回来啦

    第一次尝试使用markdown文本,可能编辑不好,见谅咕咕咕

    题目

    (这个网站里有全部蓝书的题目,qq登录即可,good)

    咳咳下面步入正题,关于这种题目,看到的第一眼应该能想到相当于动规的递推,但是要求边界如果直接dfs,30000的数据不知道你家的栈能不能的住
    所以这个题目提供了一个很好的思路,就是先求出拓扑序然后反过来一个一个求,这样可以保证求当前节点数据时(小于等于30000不用longlong)所用到的节点都以经算好了,就这么简单

    就这么简单??

    你好好考虑过动归方程了吗?
    f(x)={x}并(所有f(y)的并,存在有向边(x,y))
    为甚不是加??
    因为有可能会有重复。比如3->4,2->4那直接加起来,4就会算两次
    怎么破??

    主角闪亮登场!!

    状压

    用N位二进制数,反之一个点到其他点只有能与不能
    1就是能呗,2就是不能呗
    实现:

    1. 数组实现(不够装逼)
    2. bitset!

    一直不知道bitset怎么用
    今天先码几个呗( 嘤嘤嘤

    1:定义

    bitset<大小>名称
    bitset<大小>名称[数组大小]

    2:运算

    假设有bit[30001]
    可以直接赋值bit[1][1]=1;
    或者bit[1]="10011"; 注意是字符串,前面补0
    就是第一个1位为1

    可以直接bit[1]|bit[2] (全部按位或)

    2019.12.15 20.14--------------------

    3:复杂度

    bitset 就是通过固定的优化,使得一个字节的八个比特能分别储存 8 位的 0/1 。
    对于一个 4 字节的 int 变量,bitset 占用空间只是其1/32,计算一些信息时,所需时间也是其1/32。 --来源
    赚啊 滑稽

    4:成员函数

    .count()返回1的个数
    其实还有很多,但最多用的(状压中)也就是这个了吧

    ——————————
    下面也就是状压的常规操作了,也没啥好说的了。下面到了最快乐的

    code time
    //CH2101
    #include<iostream>
    #include<bitset>
    #include<queue>
    using namespace std;
    #define N 30005
    
    bitset<N> bit[N];
    queue<int>q;
    struct xx{
        int to,nxt;
    }e[N];int hd[N],num;
    
    inline void add(int fm,int to){
        e[++num].to=to;e[num].nxt=hd[fm];
        hd[fm]=num;
    }
    int topo[N],d[N],cnt;
    int n,m;
    
    void tp(){
        for(int i=1;i<=n;i++)
        if(!d[i])q.push(i),topo[++cnt]=i;
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int t=hd[x];t;t=e[t].nxt){
                int y=e[t].to;
                d[y]--;
                if(!d[y])q.push(y),topo[++cnt]=y;
            }
        }
    }
    int main(){
        cin>>n>>m;
        for(int x,y,i=1;i<=m;i++){
            cin>>x>>y;
            add(x,y);
            d[y]++;
        }
        tp();
        for(int i=cnt;i;i--){  //由于这是按tp序来的,所有子节点都以经ok了
            int x=topo[i];
            bit[x][x]=1;
            for(int t=hd[x];t;t=e[t].nxt){
                bit[x]|=bit[e[t].to];  //可以直接按位或
            }
        }
        for(int i=1;i<=n;i++) cout<<bit[i].count()<<endl;
        // char c=getchar();
        return 0;
    }
    
  • 相关阅读:
    《梦断代码》读书笔记(二)
    周总结(十三)
    周总结(十)
    知识圈APP开发记录(十六)
    《梦断代码》读书笔记(一)
    知识圈APP开发记录(十五)
    朴素贝叶斯
    单源最短路径 djkstra
    有向图 拓扑排序 文件依赖下的编译顺序该如何确定?
    《人类简史》读后感
  • 原文地址:https://www.cnblogs.com/Q-M-double-j/p/12045688.html
Copyright © 2020-2023  润新知