STL中的BITSET运用

胡小兔的OI博客C++ bitset 常用函数及运算符

对于一个叫做foo的bitset:

  foo.size() 返回大小(位数)
  foo.count() 返回1的个数
  foo.any() 返回是否有1
  foo.none() 返回是否没有1
  foo.set() 全都变成1
  foo.set(p) 将第p + 1位变成1
  foo.set(p, x) 将第p + 1位变成x
  foo.reset() 全都变成0
  foo.reset(p) 将第p + 1位变成0
  foo.flip() 全都取反
  foo.flip(p) 将第p + 1位取反
  foo.to_ulong() 返回它转换为unsigned long的结果,如果超出范围则报错
  foo.to_ullong() 返回它转换为unsigned long long的结果,如果超出范围则报错
  foo.to_string() 返回它转换为string的结果

hihocoder1513

  题目大意:求对于每个人来说,5门功课的名次都比他靠前的人数。

  由提示中,我们就知道需要用bitset用解这题,(否则的话五维偏序得CDQ分治和数据结构套来套去)。主要思路就是如果我们知道单独每个科目名次靠前的集合,那么就是求5个集合的交集,但这个求交集上如果是用暴力的方法很明显会超时,这时候就需要运用到bitset了,其实c++/Java中的一种数据结构类似于数组,但可以直接对其做位运算。这样我们知道每个人的每门功课排第几,那么我们也可以知道每门功课排第几是谁。这样的话,bitset比当前名次靠前的人,如100100,就表示这么功课比当前名次靠前的有第0个人,和第3个人(我习惯从0开始),类似状压的思想。

 1 #include<cstdio>
 2 #include<bitset>
 3 using namespace std;
 4 const int N=30118;
 5 int a[N][6],b[6][N];
 6 //a[i][j]第i个人第j门功课排第几, b[i][j]第i功课排第j的是谁 
 7 bitset<N> c[6][N],ans;//c[i][j]第i门功课排第j的人,名次比他高的有谁 
 8 int main()
 9 {
10     int n;
11     while(~scanf("%d",&n))
12     {
13         for(int i=0;i<n;i++)
14             for(int j=0;j<5;j++)
15             {
16                 scanf("%d",&a[i][j]);
17                 a[i][j]--;//因为我是从0开始的,所以这里-- 
18                 b[j][a[i][j]]=i;
19                 c[j][i].reset();
20             }
21         for(int i=0;i<5;i++)
22             for(int j=1;j<n;j++)
23             {
24                 c[i][j]=c[i][j-1];
25                 c[i][j].set(b[i][j-1]);
26             }
27         for(int i=0;i<n;i++)
28         {
29             ans=c[0][a[i][0]];
30             for(int j=1;j<5;j++)
31                 ans&=c[j][a[i][j]];
32             printf("%d\n",ans.count());
33         }
34     }
35     return 0;
36 }
二进制tql

  更多的见nimphy【整理】STL中的bitset(二进制华丽解决假五维偏序题)

 

posted @ 2019-05-07 12:55  新之守护者  阅读(324)  评论(0编辑  收藏  举报