Problem

Description

某大学每年都会有一次 \(Mystery\ Hunt\) 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会。

作为新生的你,对这个活动非常感兴趣。你每天都要从西向东经过教学楼一条很长的走廊,这条走廊是如此的长,以至于它被人戏称为 \(Infinite\ Corridor\) 。一次,你经过这条走廊的时候,注意到在走廊的墙壁上隐藏着 \(n\) 个等长的二进制的数字,长度均为 \(m\) 。你从西向东将这些数字记录了下来,形成一个含有 \(n\) 个数的二进制数组 \(a_1, a_​2 \cdots, a_​n\) 。

很快,在最新的一期 \(Voo\ Doo\) 杂志上,你发现了 \(q\) 个长度也为 \(m\) 的二进制串 \(r_1, r_​2, \cdots, r_​q\) 。

聪明的你很快发现了这些数字的含义。

保持数组 \(a_1, a_​2 \cdots, a_n\) 的元素顺序不变,你可以在它们之间插入 \(\land\)(按位与运算)或者 \(\vee\)(按位或运算)两种二进制运算符。例如: \(11011 \land 00111 = 00011,11011 \vee 00111 = 11111\) 。

你需要插入恰好 \(n\) 个运算符,相邻两个数之间恰好一个,在第一个数的左边还有一个。如果我们在第一个运算符的左边补入一个 \(0\) ,这就形成了一个运算式,我们可以计算它的值。与往常一样,运算顺序是从左往右。有趣的是,出题人已经告诉你这个值的可能的集合—— \(Voo Doo\) 杂志里的那一些二进制数 \(r_1, r_​2, \cdots, r_q\) ,而解谜的方法,就是对 \(r_1, r_​2, \cdots, r_q\) 中的每一个值 \(r_i\) ,分别计算出有多少种方法填入这 \(\mathbf{n}\) 个运算符,使得这个运算式的值是 \(r_i\) 。

然而,\(Infinite\ Corridor\) 真的很长,这意味着数据范围可能非常大。因此,答案也可能非常大,但是你发现由于谜题的特殊性,你只需要求答案模\(1000000007(10 ^ 9 + 7\) , 一个质数)的值。

Input Format

第一行三个数\(n,m,q\),含义如题所述。

接下来\(n\)行,其中第\(i\)行有一个长度为\(m\)的二进制串,左边是最高位,表示\(a_i\)。

接下来\(q\)行,其中第\(i\)行有一个长度为\(m\)的二进制串,左边是最高位,表示\(r_i\)。

Output Format

输出\(q\)行,每行一个数,其中第\(i\)行表示对应于\(r_i\)的答案。

Sample

Input 1

5 5 1
01110
11011
10000
01010
00100
00100

Output 1

6

Input 2

10 10 3
0100011011
0110100101
1100010100
0111000110
1100011110
0001110100
0001101110
0110100001
1110001010
0010011101
0110011111
1101001010
0010001001

Output2

69
0
5

Explanation

Explanation for Input 1

有以下且仅有以下六个运算式的值是\(00100_{2}\):(下标2表示被标识的数是二进制数)

\(0 \land \ 01110_{2} \land \ 11011_{2} \vee {\ 10000}_{2}{\ \land 01010}_{2}{\ \vee 00100}_{2}\)

\(0 \vee \ 01110_{2}\ {\vee 11011}_{2}\ \land {\ 10000}_{2}{\ \ \land 01010}_{2}{\ \vee 00100}_{2}\)

\(0 \land \ 01110_{2}\ {\vee 11011}_{2} \land {\ 10000}_{2}{\ \land 01010}_{2}{\ \vee 00100}_{2}\)

\(0 \vee \ 01110_{2} \land \ 11011_{2} \land {\ 10000}_{2}{\land \ 01010}_{2}{\ \vee 00100}_{2}\)

\(0 \land \ 01110_{2}\ {\land 11011}_{2} \land {\ 10000}_{2}{\ \land 01010}_{2}{\ \vee 00100}_{2}\)

\(0 \vee \ 01110_{2}\ \vee 11011_{2} \vee {\ 10000}_{2}{\ \ \vee 01010}_{2}{\ \land 00100}_{2}\)

Range

对于 \(10\%\) 的数据,\(n \leq 20, m \leq 30, \ q = 1\)

对于另外 \(20\%\) 的数据,\(n \leq 1000, m \leq 16\)

对于另外 \(40\%\) 的数据,\(n \leq 500, m \leq 1000\)

对于 \(100\%\) 的数据,\(1 \leq n \leq 1000, \ 1 \leq m \leq 5000, \ 1 \leq q \leq 1000\)

Algorithm

基数排序可能算一个???

Mentality

这个题看起来超级吓人 \(......\) 难度看起来确实挺大的样子。

但是我们应该冷静思考,先看看数据范围,\(10^3\) 左右,这大概就只有 \(O(nm)\) 的复杂度才能过了,最多带点小常数,连 \(log\) 都带不起。

辣么怎么办呢?冷静分析的话,我们决定单独来按位思考,想想每个二进制数的某一位经过运算的结果。

首先,我们发现每一位的运算符只有四种情况:

\(\&0,\&1,|0,|1\)

而我们需要学会发现这四种情况里没啥用的情况,那就是 \(\&1\) 和 \(|0\) 这两个运算,它们对于运算结果没有任何影响。那么有影响的就只剩下了两种情况:当前位为 \(1\) 的时候,我们插入 \(|\) 符号将会使得结果必定为 \(1\) ,否则结果不变;当前位为 \(0\) 的时候,我们插入 \(\&\) 符号会使得结果必定为 \(0\) 。否则结果不变。

那么我们需要做的就变得很简单了:如果询问中这一位为 \(1\) ,那么我们必需确保最后一个有效的操作 (\(\&0\) 和 \(|1\)) 为 \(|1\) ,如果这一位为 \(0\) ,则必须确保最后一个有效操作为 \(\&0\) 或者没有有效操作 (初始值为 \(0\)) 。

接着就是一个异常巧妙的转化了:

由于我们发现 \(\&1\) 和 \(|0\) 这两个东西对结果没有任何影响,那么我们开开脑洞:我们认为 \(\&\) 和 \(1\) 是等价的,\(|\) 和 \(0\) 是等价的!

然后脑洞不要停,我们将当前位每个数前插入运算符构成一个 \(01\) 串来看,设这个串为 \(opt\) ,其中的 \(\&\) 运算代表的值就直接设为 \(1\) ,\(|\) 运算代表的值直接设为 \(0\) 。那么我们发现,将 \(opt\) 与当前位的数构成的 \(01\) 串对其后,如果数为 \(1\) ,而 \(opt\) 的相同位置为 \(1\) 的话,这一位上的二进制值就是相等的,这符合我们等价的脑洞。

接着,我们会异常惊喜地发现一件事情,根据之前的说法,如果我们要使运算的结果为 \(1\) ,那么最后一个有效的操作必须为 \(|1\) ,则对于最后一个有效操作的位置往后,都必须是等价操作 (也即无效操作) 。

而最后一个要求结果为 \(1\) 的有效操作位置,我们必须填入 \(|\) ,也就是在 \(opt\) 串的相同位置,我们的值为 \(0\) ,而我们此位置往后的位置又全部相等!

想到了什么吗?对!如果我们将 \(n\) 个数的当前位提出来,从后往前构成一个二进制数的话,我们必须大于当前 \(opt\) 串代表的二进制数!

举个例子:

这是 \(n\) 个数的当前位:\(1010111\)

若要使结果为 \(0\) ,假设我们最后一个有效操作在第 \(5\) 位,那么最后两位的运算操作都必须为 \(\&\) 运算,也就是 \(1\) ,那么我们的操作串如下,\(.\) 代表既可以填 \(1\) 有可以填 \(0\) 。

\(opt:\ ....011\)

当前位倒过来之后为:\(1110101\)

操作串倒过来之后为:\(opt:\ 110....\)

\(opt<\) \(n\) 个数当前位构成的串

总结陈词,我们设 \(b_i\) 为 \(n\) 个数的第 \(i\) 位提出来再倒过来组成的二进制数,那么若 \(r_i\) 的第 \(j\) 位为 \(1\) ,我们必须保证我们的操作串 \(opt< b_j\) ,而我们已经证明过了,这是必然要求,那么换而言之,如果 \(opt\ge b_j\) ,这一位的结果就必定为 \(0\) 。

于是我们的题目变成了好玩的比大小游戏,我们只需要根据 \(m\) 个和 \(opt\) 有关的不等式得出结果就好了 \(hhhg\) 。

那这题的做法出来了!

先预处理出 \(b\) 数组并排序。

对于当前询问,我们找到满足 \(r_i=0\) 的最大 \(b_i\) ,设当前 \(i\) 为 \(L\) ,满足 \(r_i=1\) 的最小 \(b_i\) ,设当前 \(i\) 为 \(R\) ,那么最后的答案肯定就是 \(b_R-b_L\) 啊 \(hhhhh\) 。

当然注意当 \(L>R\) 输出 \(0\) 。

您问我怎么排序?当然是基数排序啊!常数只有 \(2\) 的 \(O(nm)\) 排序算法。

但是如果您不知道基数排序我就没办法了 \(QwQ\) ,学一下吧,挺简单的。

Code

#include <cstdio>
#include <iostream>
using namespace std;
const int mod = 1e9 + 7;
int n, m, Q, tag[2], ra[5002], rb[5002], num[5001], mi[1002], t[5002];
char s[5002], q[5002];
void Mod(int &x) { x = (x % mod + mod) % mod; }
int main() {
cin >> n >> m >> Q;
mi[1] = 1;
for (int i = 2; i <= n + 1; i++)
mi[i] = (mi[i - 1] << 1) % mod; //预处理一下幂
for (int i = 1; i <= m; i++) ra[i] = i; //排名
for (int i = 1; i <= n; i++) {
scanf("%s", s + 1);
tag[0] = 0, tag[1] = m; //基排的桶
for (int j = 1; j <= m; j++) {
Mod(num[j] += s[j] == '1' ? mi[i] : 0); //处理 b 数组的值
if (s[j] == '0') tag[0]++;
}
for (int j = m; j >= 1; j--)
rb[tag[s[ra[j]] - '0']--] = ra[j]; //获取下一轮排名
swap(ra, rb); //更新排名
}
ra[m + 1] = m + 1;
num[m + 1] =
mi[n +
1]; //因为如果要求的结果中没有 1 ,那么操作串大小上限就是 2^n-1 了。
while (Q--) {
scanf("%s", q + 1);
int l = 0, r = m + 1;
for (int i = 1; i <= m; i++)
if (q[ra[i]] == '1') {
r = i;
break;
} //找到最小的
for (int i = m; i >= 1; i--)
if (q[ra[i]] == '0') {
l = i;
break;
} //找到最大的
if (l > r)
cout << "0\n";
else
printf("%d\n", ((num[ra[r]] - num[ra[l]]) % mod + mod) % mod);
}
}

【HNOI 2018】寻宝游戏的更多相关文章

  1. [HNOI 2018]寻宝游戏

    Description 题库链接 给出 \(n\) 个 \(m\) 位的二进制数,在每一个二进制数间插入一个 & 或 | ,第 \(0\) 个数为 \(0\) , \(0,1\) 间也要插入符 ...

  2. [Bzoj5285][洛谷P4424][HNOI/AHOI2018]寻宝游戏(bitset)

    P4424 [HNOI/AHOI2018]寻宝游戏 某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新生 ...

  3. 【HNOI 2018】游戏

    Problem Description 一次小 \(G\) 和小 \(H\) 在玩寻宝游戏,有 \(n\) 个房间排成一列,编号为 \(1,2,-,n\),相邻房间之间都有 \(1\) 道门.其中一部 ...

  4. 洛谷P4424 [HNOI/AHOI2018]寻宝游戏(思维题)

    题意 题目链接 Sol 神仙题Orz Orz zbq爆搜70.. 考虑"与"和"或"的性质 \(0 \& 0 = 0, 1 \& 0 = 0\) ...

  5. BZOJ5285 & 洛谷4424 & UOJ384:[HNOI/AHOI2018]寻宝游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5285 https://www.luogu.org/problemnew/show/P4424 ht ...

  6. [HNOI/AHOI2018]寻宝游戏

    题目大意: $n(n\le1000)$个$m(m\le5000)$位的二进制数,第$0$个数为$0$.用$\wedge$和$\vee$将这些数连接起来.$q(q\le1000)$次询问,每次给定一个$ ...

  7. 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)

    点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...

  8. P3320 [SDOI2015]寻宝游戏 解题报告

    P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...

  9. [BZOJ3991][SDOI2015]寻宝游戏

    [BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...

  10. 【BZOJ】【3991】【SDOI2015】寻宝游戏

    dfs序 我哭啊……这题在考试的时候(我不是山东的,CH大法吼)没想出来……只写了50分的暴力QAQ 而且苦逼的写的比正解还长……我骗点分容易吗QAQ 骗分做法: 1.$n,m\leq 1000$: ...

随机推荐

  1. ffmpeg快速获取视频截图

    使用ffmpeg可以非常方便的生成视频截图,命令行下的mplayer也可以做视频截图,只不过mplayer在本质上还是调用ffmpeg来实现.ffmpeg 通过指定 -vcodec 参数为 mjpeg ...

  2. MSSQL:查看所有触发器信息的命令

    转自:http://www.2cto.com/database/201307/228708.html 编写程序,有时或为了偷懒,或为更简单地实现所需功能,使用了触发器.这可是把双刃剑,用得不好,程序出 ...

  3. [本体论][UML][统一建模语言][软件建模][OWL]从本体论到UML到OWL

    以下内容,是关于软件建模的方法与思路. UML与OWL都是基于本体论的建模语言. 本体论(哲学) 本体论(信息科学) UML(统一建模语言) more info 参考:[设计语言][统一建模语言][软 ...

  4. Python cffi学习

    cffi是连接Python与c的桥梁,可实现在Python中调用c文件.cffi为c语言的外部接口,在Python中使用该接口可以实现在Python中使用外部c文件的数据结构及函数. 由于资料较少,所 ...

  5. Linux 两台服务器之间传输文件

    一.scp命令的使用 1.传输文件(不包括目录) 命令格式:scp 源文件路径目录/需要传输的文件 目标主机的用户名@目标主机IP/主机别名:目标主机存储目录 举个例子:scp /root/ceshi ...

  6. 用热情点燃软件工程II

    这个作业的要求来自于:https://www.cnblogs.com/greyzeng/p/9581624.html 阅读完文章(热情.能力.选择)深有感触.文章链接为:http://coolshel ...

  7. 6种原型设计工具大比对! Axure,Invision, 墨刀……哪款适合你?

    每一年的毕业季都是找工作高峰时期,产品经理.UI设计师这些岗位都会接触到原型设计工具.选择原型设计工具最重要的一点:适合自己的才是最好的! 下文将对目前超火的原型工具进行大对比,快来看看那一款于你而言 ...

  8. 使用Sqlserver事务发布实现数据同步(zhuanqian)

    事务的功能在sqlserver中由来已久,因为最近在做一个数据同步方案,所以有机会再次研究一下它以及快照等,发现还是有很多不错的功能和改进的.这里以sqlserver2008的事务发布功能为例,对发布 ...

  9. node.js (01http 模块 url 模块)

    // 引入 http 模块-->Node.js 中的很多功能都是通过模块实现. var http = require('http'); // http.createServer() 方法创建服务 ...

  10. form提交xml文件

    --为何ajax提交不了xml?--原因:Request.Form["Data"]这种获取参数方式,原本就不是mvc路由参数获取方式,这是Asp.net中webfrom页面获取参数 ...