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