比特镇旅游(Tourist Attractions)【暴力+Bitset 附Bitset用法】
Online Judge:NOIP2016十连测第一场 T2
Label:暴力,Bitset
题目描述
在美丽的比特镇一共有n个景区,编号依次为1到n,它们之间通过若干条双向道路连接。
Byteasar 慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起 4 个景区的门票费。他可以在任意景区开始游览,然后结束在任意景区。
Byteasar 的旅游习惯比较特殊,一旦他路过了一个景区,他就一定会进去参观,并且他永远不会参观同一个景区两次。所以他想知道,有多少种可行的旅游路线,使得他可以恰好参观 4 个景区呢?即,有多少条简单路径恰好经过了 4 个点。
输入
第一行包含两个整数n,表示景区的总数。
第2至第n+1行,每行一个长度为n的01字符串,第i+1行第j个字符为0表示i和j之间没有道路,为1表示有一条道路。
输入数据保证\((i,j)\)的连接情况等于\((j,i)\)的连接情况,且\((i,i)\)恒为0。
输出
输出一行一个整数,即可行的路线总数。
样例
Input
4
0101
1010
0101
1010
Output
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。
对于40%数据,\(n<=50\)
对于70%数据,\(n<=300\)
对于100%数据,\(n<=1500\)
题解
40pts
\(O(N^4)\)枚举四个点。
70pts
\(O(N^3)\)。
考虑枚举中间两个点\(p2,p3\),现在要找到符合条件的对数{\(p1,p4\)}。需要满足的条件是这四个点两两都不相同。
设\(cnt[i]\)表示与i直接连通的点的个数(就是字符串中含1个数),\(same[i][j]\)表示与i,j都直接相连的点的个数(就是两个字符串对应位都为1的位数)。
那么上面的符合条件的对数{\(p1,p4\)}就是\((cnt[p2]-1)*(cnt[p3]-1)-same[p2][p3]\)。都减一是因为\(p2,p3\)互相相连,新选的\(p1,p4\)不能跟这两个重了。
上面的枚举是\(O(N^2)\)的,预处理\(same[][]\)是\(O(N^3)\)的。
100pts
主要瓶颈在于\(same[][]\)的预处理,其实预处理的时候就马上想到用\(Bitset\)去优化常数,快速得到这个值,但是考试的时候觉得应该有\(N^2\)解法,结果Claris的正解就是这东西???。
所以利用\(Bitset\)二进制存储,计算两者与运算结果中1的个数。
复杂度为\(O(\frac{n^3}{64})\),对于n<=1500的数据没问题。
#include<bits/stdc++.h>
using namespace std;
const int N=1510;
int n,cnt[N];
bitset<N>a[N];
int main(){
scanf("%d",&n);
register int i,j;char c;
for(i=1;i<=n;i++)for(j=1;j<=n;j++){
c=getchar();
while(c!='0'&&c!='1')c=getchar();
a[i][j]=c-'0';
cnt[i]+=c-'0';
}
long long ans=0;
for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)if(a[i][j]==1){
ans+=1ll*(cnt[i]-1)*(cnt[j]-1)-1ll*(a[i]&a[j]).count();
}
printf("%lld\n",ans<<1);
}
END
整理一下\(Bitset\)的用法。参考博客->
定义/初始化
<>中填的类似数组大小,后面可以开成单个变量,也可以开成一个数组。
bitset<LEN>a;
bitset<2333>b[N];
初始化大概有如下几种方式。
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("test.out","w",stdout);
//用string(似乎只能包含01,不然运行时会报错)
bitset<10>a (string("11011"));
cout<<"#1:"<<a<<endl;
//用整数(转为二进制)
a=123;
cout<<"#2:"<<a<<endl;
//直接像数组那样赋值(下标从0开始,长度为10)
for(int i=0;i<=9;i++){
int o;scanf("%d",&o);//测试时输入1 0 1 0 0 0 1 1 0 1
a[i]=o;
}
cout<<"#3:"<<a<<endl;
}
输出结果
#1:0000011011
#2:0001111011
#3:1011000101
运算操作
\(Bitset\)支持所有位运算。包括异或^、或|、与&、左移<<、右移>>等。
常用函数
查询类
1.返回1的个数
a.count();
2.返回是否有1
a.any();
操作类
3.全部变成1
a.set();
4.将右数第\(i+1\)位变成1(实际上就是将二进制的第i位变成1,下标从0开始)
a.set(i);
//例: a.set(2) 0000000100
5.全部变为0(()中间填数字时指定某一位,同上)
a.reset();
6.取反(()中间填数字时指定某一位,同上)
a.flip();
至于常数优化是多少,好像跟机器位数有关(32/64)。
比特镇旅游(Tourist Attractions)【暴力+Bitset 附Bitset用法】的更多相关文章
- [CSP-S模拟测试]:Tourist Attractions(简单图论+bitset)
题目描述 在美丽的比特镇一共有$n$个景区,编号依次为$1$到$n$,它们之间通过若干条双向道路连接.$Byteasar$慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起$4$个景区的门票费. ...
- csp-s模拟48,49 Tourist Attractions,养花,画作题解
题面:https://www.cnblogs.com/Juve/articles/11569010.html Tourist Attractions: 暴力当然是dfs四层 优化一下,固定两个点,答案 ...
- [JSOI2010]连通数 (dfs或tarjan或bitset)+bitset学习
题目描述 输入格式 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. 输出格式 输出一行一个整数,表示该图的连通数. 样例 样 ...
- 【JZOJ4857】Tourist Attractions(Bitset)
题意:给定一个n个点的无向图,求这个图中有多少条长度为4的简单路径. n<=1500 思路: #include<map> #include<set> #include&l ...
- D. 旅游景点 Tourist Attractions 状压DP
题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD 不希望在刚吃过一顿大餐之后立刻去下一 ...
- 旅游景点 Tourist Attractions 题解
题面在这里 再次破了纪录,连做了3天... 让我们从头来一点一点分析 1.预处理 先看题面,乍一看貌似是个图论题,有n个点m条边,给定一些必须经过的点和强制经过顺序,求一条最短路 我们发现n和m都比较 ...
- 牛客网提高组模拟赛第七场 T3 洞穴(附bitset介绍)
就是DP. 我们可以很简单的想到要枚举中间点,进行边数的转移. 但是因为边长数据范围很大,所以我们考虑log的倍增. 状态设计为\(dp[i][j][k]\),为从节点\(i\)走\(2^k\)步能否 ...
- 比特镇步行(Walk)【虚点+bfs+dfs】
Online Judge:NOIP2016十连测第一场 T3 Label:虚点,bfs,dfs 题目描述 说明/提示 对于100%数据,\(n<=200000\),\(m<=300000\ ...
- LYDSY模拟赛day1 Tourist Attractions
/* 假设路径是 a − b − c − d,考虑枚举中间这条边 b − c,计 算有多少可行的 a 和 d. 设 degx 表示点 x 的度数,那么边 b − c 对答案的贡献为 (degb − 1 ...
随机推荐
- Yii2 在php 7.2环境下运行,提示 Cannot use ‘Object’ as class name
出错原因是: Object是php7.2中的保留类名,不可以使用Object作为类的名称. The object name was previously soft-reserved in PHP 7. ...
- Yii2 使用 npm 安装的包
转载自: yii2.0.15 使用 npm 替换 bower,加速 composer 安装速度 [ 2.0 版本 ] 修改 ommon/config/main.php <?php return ...
- redis笔记_源码_字典dict
参考:https://redissrc.readthedocs.io/en/latest/datastruct/dict.html Expand: 条件: 新的table 大小: Rehash: 条件 ...
- 关于Cadence OrCad 16.6的破解
相信很多人都知道去老吴的博客上找安装包和破解文件,但是上面的自称一键式破解程序.以及破解图文说明,都是很有问题的. 首先,该一键式破解程序默认的文件后缀与该程序指向的安装压缩包后缀不一致:其次,该程序 ...
- C++利用动态数组实现顺序表(不限数据类型)
通过类模板实现顺序表时,若进行比较和遍历操作,模板元素可以通过STL中的equal_to仿函数实现,或者通过回调函数实现.若进行复制操作,可以采用STL的算法函数,也可以通过操作地址实现.关于回调函数 ...
- C++——类的多继承
多继承概念 一个类有多个直接基类的继承关系称为多继承 多继承声明语法 class 派生类名 : 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n { 数据成员和成 ...
- linxu(centos)安装nginx
安装make: yum -y install gcc automake autoconf libtool make 安装g++: yum install gcc gcc-c++ 下面正式开始 ---- ...
- 几个 GetHashCode 函数
几个 GetHashCode 函数: DBTables.pas Delphi/Pascal code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
- Windows的DOS命令
f: d: ...
- Java核心-01 谈谈你对Java平台的理解
今天我要问你的问题是,谈谈你对 Java 平台的理解?“Java 是解释执行”,这句话正确吗? 典型回答 Java本身是一种面向对象的语言,最显著的特性有两个.一是所谓的“书写一次,到处运行”,能够非 ...