题意

题目链接

Sol

神仙题Orz

Orz zbq爆搜70。。

考虑"与"和"或"的性质

\(0 \& 0 = 0, 1 \& 0 = 0\)

\(0 \mid 1 = 1, 1 \mid 1 = 1\)

也就是说某一个数\(\& 0\)之后不管之前是什么,现在的值变为\(0\)

某一个数\(\mid 1\)之后不管之前的是什么,现在的值变为\(1\)

继续考虑

\(0 \& 1 = 0, 1 \& 1 = 1\)

\(0 \mid 0 = 0, 1 \mid 0 = 1\)

这个时候我们把\(\&\)看做是1,\(\mid\)看做是\(0\)

那么对于上面这两条式子,可以看出若某个数和前面的运算符相同,之前的值不会发生改变

这时候考虑如何计算答案,对于每次询问,若某一位上是\(1\)

那么我们把每一列上的数和他之前的操作符分别拿出来看成一些序列,显然这个序列要满足最后一个\(\mid 1\)要在\(\& 0\)之后

那么这两个序列应该长这个样子:

\(101010 \dots 0 \dots 1\)

\(101010 \dots 1 \dots 0\)

我们会惊奇的发现,第一个式子一定大于第二式子。同理如果询问的位置是\(0\)的话,第一个式子应该小于第二个式子

又因为第二个式子的\(0/1\)可以任意取。那么答案应该是\(min_1 - max_0\),\(min_1\)表示询问位置上的值是\(1\)对应的列的最小值(每一列的第一行是最低位)。

这样的复杂度是\(O(nmq)\)

实际上每次询问至于每一列的大小有关,我们可以先按照字符串的大小排一遍序(搞出类似后缀数组中的sa和rak数组),这样每次询问就只需要计算两个串的答案了

复杂度:\(O(mn\log m + mq)\)

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 5e5 + 10, INF = 1e9 + 7, mod = 1000000007;
template<typename A, typename B> inline void chmax(A &x, B y) {
x = x > y ? x : y;
}
template<typename A, typename B> inline void chmin(A &x, B y) {
x = x < y ? x : y;
}
template<typename A, typename B> inline void add2(A &x, B y) {
x = (x + y >= mod ? x + y - mod : x + y);
}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, Q, v[MAXN], rak[MAXN], po2[MAXN], sa[MAXN], val[MAXN];
char a[1002][5002], q[5001];
int comp(const int &x, const int &y) {
for(int i = N; i >= 1; i--)
if(a[i][x] == '0' && a[i][y] == '1') return 1;
else if(a[i][x] == '1' && a[i][y] == '0') return 0;
return 0;
}
int trans(int id) {
int ans = 0;
for(int i = N; i >= 1; i--)
if(a[i][id] == '1') add2(ans, po2[i - 1]);
return ans;
}
int main() {
// freopen("a.in", "r", stdin);
N = read(); M = read(); Q = read(); po2[0] = 1;
for(int i = 1; i <= N; i++) scanf("%s", a[i] + 1), po2[i] = (po2[i - 1] * 2) % mod;
for(int i = 1; i <= N; i++) a[i][M + 1] = '1', a[i][0]= '0';
for(int i = 1; i <= M + 1; i++) sa[i] = i;
sort(sa + 1, sa + M + 2, comp);
for(int i = 1; i <= M + 1; i++) rak[sa[i]] = i;
for(int i = 1; i <= M + 1; i++) val[i] = trans(i); val[M + 1]++;//不++就比答案少1,加了莫名其妙就过了。。。
for(int i = 1; i <= Q; i++) {
scanf("%s", q + 1);
int r = M + 1, l = 0;
for(int j = 1; j <= M; j++)
if(q[j] == '1') chmin(r, rak[j]);
else chmax(l, rak[j]);
if(l > r) puts("0");
else cout << (val[sa[r]] - val[sa[l]] + mod) % mod << '\n';
}
return 0;
}
/*
3
0 1 1
5 7 3
*/

洛谷P4424 [HNOI/AHOI2018]寻宝游戏(思维题)的更多相关文章

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

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

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

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

  3. [洛谷P4436] HNOI/AHOI2018 游戏

    问题描述 一次小G和小H在玩寻宝游戏,有n个房间排成一列,编号为1,2,...,n,相邻的房间之间都有一道门.其中一部分门上锁(因此需要有对应的钥匙才能开门),其余的门都能直接打开.现在小G告诉了小H ...

  4. 【洛谷4424】[HNOI_AHOI2018]寻宝游戏(我也不知道括号里该写啥)

    题目 洛谷 4424 分析 感觉思路比较神仙. 对于按位与和按位或两种运算,显然每一位是独立的,可以分开考虑. 对于某一位,「与 \(0\)」会将这一位变成 \(0\),「或 \(1\)」会将这一位变 ...

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

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

  6. 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)

    题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ...

  7. 洛谷P4438 [HNOI/AHOI2018]道路(dp)

    题意 题目链接 Sol 每当出题人想起他出的HNOI 2018 Day2T3,他都会激动的拍打着轮椅 读题比做题用时长系列... \(f[i][a][b]\)表示从根到\(i\)的路径上,有\(a\) ...

  8. 洛谷P4425 [HNOI/AHOI2018]转盘(线段树)

    题意 题目链接 Sol 首先猜一个结论:对于每次询问,枚举一个起点然后不断等到某个点出现时才走到下一个点一定是最优的. 证明不会,考场上拍了3w组没错应该就是对的吧... 首先把数组倍长一下方便枚举起 ...

  9. [HNOI/AHOI2018]寻宝游戏

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

随机推荐

  1. 人脸识别准备 -- 基于raspberry pi 3b + movidius

    最近准备系统地学习一下深度学习和TensorFlow,就以人脸识别作为目的. 十年前我做过一些图像处理相关的项目和研究,涉及到图像检索.记得当时使用的是SIFT特征提取,该特征算子能很好地抵抗图像旋转 ...

  2. 在Azure DevOps Server的代理服务器安装Python环境

    Python和Azure DevOps Server Python是一种计算机程序设计语言.是一种动态的.面向对象的脚本语言,最初主要为系统运维人员编写自动化脚本,在实际应用中,Python已经在前端 ...

  3. Redis 客户端命令总结

    注意:括号里是参数,具体使用的时候不需要括号和逗号,直接使用空格分隔命令以及各个参数即可. 1.对Key操作的命令 exists(key):确认一个key是否存在.存在返回1,不存在返回0. del( ...

  4. 微信开发-PC调试-JS-SDK功能之分享功能调试

    一般涉及和第三方的开发调试,都会比较麻烦些.不过,像微信这样的大公司呢,产品技术是过硬的,所以,基本上只要自己把文档看仔细了,弄好了,基本就没有问题了. 对于后端接口一类的调试,主要就是通过打印访问日 ...

  5. Redis简明教程

    redis是什么: Redis is an open source, BSD licensed, advanced key-value store. It is often referred to a ...

  6. linux系统中的文件权限详解(转)

    一.在<Linux系统中如何查看文件属性>中介绍了通过ls指令来查看文件的属性,具体如下: [命令] letuknowit@ubuntu:/$ cd /tmp letuknowit@ubu ...

  7. 在Hadoop集群上的Hive配置

    1. 系统环境Oracle VM VirtualBoxUbuntu 16.04Hadoop 2.7.4Java 1.8.0_111 hadoop集群master:192.168.19.128slave ...

  8. 3分钟看完Java 8——史上最强Java 8新特性总结之第三篇 函数式编程技巧

    目录 · 改写设计模式 · 策略模式(Strategy Pattern) · 模板方法模式(Template Method Pattern) · 观察者模式(Observer Pattern) · 责 ...

  9. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...

  10. 【leet-code】712. 两个字符串的最小ASCII删除和

    题目描述 给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 = "eat" ...