zoukankan      html  css  js  c++  java
  • POJ 2443 Set Operation 题解

    本文同时发布于

    博客园

    洛谷博客

    题目链接

    题目分析

    给你n个集合,每个集合里面都有可能会重复的数字

    q个询问,每次询问两个数是否会在同一集合内

    $n<=1000$

    $q<=200000$


    做法分析

    算法一: $mathcal{O}(nq)$ 的暴力做法

    $vis[x][i]$ 表示 x 是否出现在第 $i$ 个集合中,是为1,否为0

    每一次询问枚举

    算法二: 状态压缩压掉第二维

    时间复杂度 $mathcal{O}(n+q)$

    但是 $n<=1000$ 范围会爆空间

    具体做法:

    $vis[x]$ 表示 $x$ 所包括的集合,如果 $x$ 在第 $i$ 个集合中出现,则第 $i$ 位为 $1$ (二进制位)

    储存操作: 第 $i$ 个集合读到 $x$ 时,则 $vis[x]|=(1<<i)$

    查询操作: 查询 $x$ 和 $y$ 是否在同一集合内出现过,就是查询 $vis[x]&vis[y]$ 是否为 $1$

    但是显然就算使用 unsigned long long 也经不过 $nleq 1000$ 的数据范围

    参考Code:

    #include<iostream>
    #include<cstdio>
    #include<bitset>
    using namespace std;
    int vis[10010];
    int n,q,c,x,y;
    bool f;
    inline int read()
    {
        int r=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')
            ch=getchar();
        while(ch>='0'&&ch<='9'){
            r=(r<<3)+(r<<1)+(ch^48);
            ch=getchar();
        }
        return r;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            c=read();
            for(int j=1;j<=c;j++)
            {
                x=read();
                vis[x]|=(1<<i);
            }
        }
        q=read();
        for(int i=1;i<=q;i++)
        {
            x=read();y=read();
            if(vis[x]&vis[y])
                puts("Yes");
            else
                puts("No");
        }
        return 0;
    }

    算法三: 用bitset对算法二进行优化

    奇技淫巧bitset是一个极其好用的STL,类似于bool数组却比bool数组支持更多的操作,更快,占用空间更小

    关于具体的bitset的各种操作珂以去网上找找

    bitset在#include<bitset>头文件里

    bitset<1010>vis[10010]这样就声明了10010个bitset

    每一个bitset共有1010个bit,每个bit为1或0,初始都为0

    bitset也支持按位与,按位或,按位异或,左移右移等操作等操作.

    而且占用空间也小,一个bool是1byte,而bitset的一位只占1bit

    时间复杂度$mathcal{O}(n+q)$

    参考Code:

    #include<iostream>
    #include<cstdio>
    #include<bitset>
    using namespace std;
    bitset<1010>tmp,vis[10010];
    int n,q,c,x,y;
    bool f;
    inline int read()
    {
        int r=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')
            ch=getchar();
        while(ch>='0'&&ch<='9'){
            r=(r<<3)+(r<<1)+(ch^48);
            ch=getchar();
        }
        return r;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            c=read();
            for(int j=1;j<=c;j++)
            {
                x=read();
                vis[x][i]=1;//存入可以按正常的bool数组写
            }
        }
        q=read();
        for(int i=1;i<=q;i++)
        {
            x=read();y=read();
            tmp=vis[x]&vis[y];
            if(tmp.count()!=0)
                puts("Yes");
            else
                puts("No");
        }
        return 0;
    }
  • 相关阅读:
    unsupported jsonb version number 123
    如何在MPlayer上支持RTSP
    TDengine 时序数据库的 ADO.Net Core 提供程序 Maikebing.EntityFrameworkCore.Taos
    如何使用IoTSharp对接ModBus?
    如何从源码启动和编译IoTSharp
    Asp.Net Core 自动适应Windows服务、Linux服务、手动启动时的内容路径的扩展方法
    MQTTnet 的Asp.Net Core 认证事件的扩展
    Asp.Net Core 中利用QuartzHostedService 实现 Quartz 注入依赖 (DI)
    The remote certificate is invalid according to the validation procedure 远程证书验证无效
    settings插拔式源码
  • 原文地址:https://www.cnblogs.com/do-while-true/p/12373385.html
Copyright © 2011-2022 走看看