zoukankan      html  css  js  c++  java
  • STL : bitset

    之前一直不知道bitset具体的原理,只知道一部分用法。

    今天考了一道bitset优化的题,就抽了一些时间研究了一下bitset。

    1.原理

    就是二进制压位。

    具体的可以看一下那道题:

    在美丽的比特镇一共有n 个景区,编号依次为1 到n,它们之间通过若干条双向道路连接。

    Byteasar 慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起4 个景区的门票费。

    他可以在任意景区开始游览,然后结束在任意景区。

    Byteasar 的旅游习惯比较特殊,一旦他路过了一个景区,他就一定会进去参观,并且他永远不会参观同一个景区两次。

    所以他想知道,有多少种可行的旅游路线,使得他可以恰好参观4 个景区呢?即,有多少条简单路径恰好经过了4 个点。

    Input

    第一行包含两个整数n,表示景区的总数。

    第2 至第n + 1 行,每行一个长度为n 的01 字符串,第i + 1 行第j 个字符为0 表示i 和j 之间没有道路,为1 表示有一条道路。

    输入数据保证(i; j) 的连接情况等于(j; i) 的连接情况,且(i; i) 恒为0。

    Output

    输出一行一个整数,即可行的路线总数。

    Examples

    tour.in

    4

    0101

    1010

    0101

    1010

    tour.out

     8

    8 条路线分别为:

    1->2->3->4,4->3->2->1,

    2->3->4->1,1->4->3->2,

    3->4->1->2,2->1->4->3,

    4->1->2->3,3->2->1->4。

    Notes

    测试点编号     n

         1              = 5

         2              = 10

         3              = 20

         4              = 50

         5              = 300

         6              = 300

         7              = 300

         8              = 1500

         9              = 1500

         10            = 1500

    标程在这里(标程手写bitset,太巨了%%%):

     1 #include<cstdio>
     2 const int N=1510;
     3 int cnt[65536],m,n,i,j,d[N];char g[N][N];long long ans;
     4 int popcount(unsigned int x){return cnt[x>>16]+cnt[x&65535];}
     5 struct BIT{
     6   unsigned int v[47];
     7   void set(int x){v[x>>5]|=1U<<(x&31);}
     8   void count(const BIT&b){for(int i=0;i<=m;i++)ans-=popcount(v[i]&b.v[i]);}
     9 }f[N];
    10 int main(){
    11   freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);
    12   for(i=1;i<65536;i++)cnt[i]=cnt[i>>1]+(i&1);
    13   scanf("%d",&n);m=(n-1)>>5;
    14   for(i=0;i<n;i++){
    15     scanf("%s",g[i]);
    16     for(j=0;j<n;j++)if(g[i][j]=='1')f[i].set(j),d[i]++;
    17   }
    18   for(i=0;i<n;i++)for(j=0;j<i;j++)if(g[i][j]=='1')ans+=(d[i]-1)*(d[j]-1),f[i].count(f[j]);
    19   printf("%I64d",ans*2);
    20   fclose(stdin);fclose(stdout);
    21   return 0;
    22 }
    标程

    2.使用方法

    定义:

    bitset<666>x;    //定义一个包含666位的bitset叫做x 
    bitset<666>x(0xfa2);    //赋初值 
    bitset<666>x(string("0101111001"));    //另一种赋初值 

    常用函数:

    x.size();    //返回x的位数 
    x.set();    //将x的所有位设为1
    x.set(k);    //将x的第k位设为1
    x.set(k,a);    //将第k位设为a 
    x.reset();    //将x的所有位设为0
    x.reset(k);    //将x的第k位设为0
    x.any();    //如果x中存在某一位是1,返回true;否则返回false
    x.none();    //如果x中所有位都是0,返回true;否则返回false
    x.count();    //返回x中1的个数
    x.test();    //返回x的第k位的值
    x.flip();    //翻转x的所有位的值(0变成1,1变成0)
    x.flip(k);    //翻转x的第k位的值
    x.to_ulong()    //返回它转换为unsigned long的结果,如果超出范围则报错
    x.to_ullong()    //返回它转换为unsigned long long的结果,如果超出范围则报错
    x.to_string()    //返回它转换为string的结果

    另外我们也可以用下标来访问、修改bitset中的位。

    int res=x[3];
    x[5]=1;

    注意下标从0开始。

    运算:

    bitset的运算类似整数。

    可以用==、!=、~、<<、>>、&、|、^、<<=、>>=、&=、|=、^=等运算符。

    3.时间&空间&应用

    可以在<bitset>头文件看出,bitset使用unsigned long进行压位的。

    也就是说空间和时间都能被bitset压缩至1/32。

    所以我们可以用bitset实现邻接矩阵等只含有0或1的数据结构,这样可以优化时间和空间。

  • 相关阅读:
    浅谈关于JavaScript解析XML文件的注意事项
    个人总结的Struts2拦截器使用和拦截栈的配置,基于注解的方式
    使用Awstats统计部署在tomcat中的网站数据
    spring4.x + hibernate4.x 配置详解
    Java内部类总结
    Java中static的使用
    Java多线程基础知识总结
    Java线程经典面试题
    C#/.net七牛云存储上传图片(文件)操作
    Special Solver Parameters
  • 原文地址:https://www.cnblogs.com/cervusy/p/9856417.html
Copyright © 2011-2022 走看看