zoukankan      html  css  js  c++  java
  • bitset及压位运算

    题面

    有N个集合和Q个询问,每个询问给定两个整数x,y,问x,y是否同时属于某个集合。

    输入

    输入一个整数N(1 <= N <= 1000),表示集合的数目。

    接下来N行,每行先输入一个整数C(1 <= C <= 10000)表示某个集合的大小。

    然后输入C个整数表示该集合的所有元素(元素是1到10000之间的整数)。

    接下来输入一个整数Q(1 <= Q <= 200000),表示询问的数目。

    接下来Q行,每行两个整数x y (1 <= x, y <= 10000)。

    输出

    对于每一个询问,判断x 与 y是否同时属于某一个集合,

    如果是输出Yes,否则输出No。

    样例

    输入

    复制
    3
    3 1 2 3
    3 1 2 5
    1 10
    4
    1 3
    1 5
    3 5
    1 10

    输出

    复制
    Yes
    Yes
    No
    No

    提示

    子任务1,20分,1 le N le 1001N100,1 le Q le 1001Q100,1 le C le 1001C100。

    子任务2,30分,元素是1到10之间的整数。

    子任务3,50分,全范围。

    分析

    原本第一反应用并查集做...但是仔细一看发现一个点可以在多个集合里,没法维护啊!

    数据范围有限制,如果就是常规标记vis[C][N]显然会爆空间,所以引入压位运算

    一个int去掉符号位是31位,而unsigned int没有符号位,所以可以用unsigned int

    总共有1000个集合,假设一个整数每一位代表一个集合,那么用(1000/32)个整数就可以表示所有集合

    如果把这大约40个整数写成二进制并且排列成矩阵

    最初:

    000000000....(每一行有32位数)

    000000000....

    .......(共有约40行)

    000000000....

    那么 i / 32表示在第几行,i % 32表示在第几列,用 | 运算更新

    查询的时候用 & 运算判断查询

    ( “ | ”运算只要有一个为1即结果为1,“ & ”运算要两个都为1结果才为1,“更新”表示更新这个数在某个集合里,“判断”表示判断两个数都在某个集合里)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    unsigned int vis[10005][42];
    //压位运算 
    int n,c,q; 
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int c;
            scanf("%d",&c);
            for(int j=1;j<=c;j++)
            {
                int x;
                scanf("%d",&x);
                vis[x][i/32]|=1<<(i%32);
                
            }
            
        }
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int x,y;
            bool flag=0;
            scanf("%d%d",&x,&y);
            for(int i=0;i<=40;i++)//0~39,注意从0开始
            {
                if(vis[x][i]&vis[y][i])
                {
                    flag=1;
                    printf("Yes
    ");
                    break;
                }
            }
            if(!flag) printf("No
    ");
        }
        return 0;
    }

    关于bitset

    bitset本质貌似就是压位(上述操作也可以用bitset实现,但是我不太了解

    这里推荐一篇博客---传送门

    update(2021.10.5),看到了同机房大佬wind_whisper的博客,简洁易懂,挂上传送门:STL:bitset用法详解

    qwq

  • 相关阅读:
    javascript 犀牛书
    Hmtl/css
    SQL Server 查询中使用Union或Union All后Order by排序无效(嵌套查询乱序)
    CSS 动画
    CSS 文字排版
    CSS 太极图
    Amazon Products 服务费估算
    CSS3 结构伪类选择器
    JS 执行机制
    vue 生命周期函数的学习
  • 原文地址:https://www.cnblogs.com/conprour/p/14731180.html
Copyright © 2011-2022 走看看