题意

题目链接

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. WeexSDK之注册Components

    先来看一下注册Components的源码: + (void)_registerDefaultComponents { [self registerComponent:@"container& ...

  2. Redis 客户端命令总结

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

  3. 人生苦短之---第一个Python程序

    第一个 Python 程序 目标 第一个 HelloPython 程序 Python 2.x 与 3​​.x 版本简介 执行 Python 程序的三种方式 解释器 —— python / python ...

  4. HoloLens开发手记 - 使用Windows设备控制台 Using Windows Device Portal

    Windows设备控制台允许你通过Wi-Fi或USB来远程控制你的HoloLens设备.设备控制台是HoloLens上的一个Web Server,你可以通过PC的浏览器来连接到它.设备控制台包含了很多 ...

  5. 13-部署traefik-ingress插件

    Kubernetes traefik ingress安装 Ingress简介 如果你还不了解,ingress是什么,可以先看下我翻译的Kubernetes官网上ingress的介绍Kubernetes ...

  6. IdentityServer4之SSO(基于OAuth2.0、OIDC)单点登录、登出

    IdentityServer4之SSO(基于OAuth2.0.OIDC)单点登录.登出 准备  五个Web站点: 1.localhost:5000 :                  认证服务器.2 ...

  7. 把本地项目放进新建的仓库(idea)

    1,获取仓库地址 比如: git@bitbucket.org:360717118/springboot_servlet-filter-listener-file.git,   2,idea 设置:

  8. SpringBoot一站式启动流程源码分析

    一.前言 由上篇文章我们得知,SpringBoot启动时,就是有很简单的一行代码.那我们可以很清楚的看到这行代码的主角便是SpringApplication了,本文我们就来聊一聊这货,来探寻Sprin ...

  9. js仿qq分组折叠效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. 记一次IDEA编译器调优

    前言: 我们知道,IDEA是用Java写的,那么他肯定也存在虚拟机的调优的问题,那么今天我们就对它进行开刀. 下面是默认参数 位置在:C:\Program Files\JetBrains\Intell ...