之前一直不知道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 }
标程

相关文章: