洛谷P4424 [HNOI/AHOI2018]寻宝游戏(思维题)
题意
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]寻宝游戏(思维题)的更多相关文章
- [Bzoj5285][洛谷P4424][HNOI/AHOI2018]寻宝游戏(bitset)
P4424 [HNOI/AHOI2018]寻宝游戏 某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新生 ...
- BZOJ5285 & 洛谷4424 & UOJ384:[HNOI/AHOI2018]寻宝游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5285 https://www.luogu.org/problemnew/show/P4424 ht ...
- [洛谷P4436] HNOI/AHOI2018 游戏
问题描述 一次小G和小H在玩寻宝游戏,有n个房间排成一列,编号为1,2,...,n,相邻的房间之间都有一道门.其中一部分门上锁(因此需要有对应的钥匙才能开门),其余的门都能直接打开.现在小G告诉了小H ...
- 【洛谷4424】[HNOI_AHOI2018]寻宝游戏(我也不知道括号里该写啥)
题目 洛谷 4424 分析 感觉思路比较神仙. 对于按位与和按位或两种运算,显然每一位是独立的,可以分开考虑. 对于某一位,「与 \(0\)」会将这一位变成 \(0\),「或 \(1\)」会将这一位变 ...
- 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)
点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...
- 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)
题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ...
- 洛谷P4438 [HNOI/AHOI2018]道路(dp)
题意 题目链接 Sol 每当出题人想起他出的HNOI 2018 Day2T3,他都会激动的拍打着轮椅 读题比做题用时长系列... \(f[i][a][b]\)表示从根到\(i\)的路径上,有\(a\) ...
- 洛谷P4425 [HNOI/AHOI2018]转盘(线段树)
题意 题目链接 Sol 首先猜一个结论:对于每次询问,枚举一个起点然后不断等到某个点出现时才走到下一个点一定是最优的. 证明不会,考场上拍了3w组没错应该就是对的吧... 首先把数组倍长一下方便枚举起 ...
- [HNOI/AHOI2018]寻宝游戏
题目大意: $n(n\le1000)$个$m(m\le5000)$位的二进制数,第$0$个数为$0$.用$\wedge$和$\vee$将这些数连接起来.$q(q\le1000)$次询问,每次给定一个$ ...
随机推荐
- Android开发 - 更"聪明"的申请权限方式
在Android6.0以后,很多权限需要动态申请,只有在用户点同意后,我们才能使用对应API,因此,正确申请权限就显得很重要. 常用方式 通常我们使用这种方式来判断权限状态: private stat ...
- dtb和dtc文件浅析
目录 dtb和dtc文件浅析 工具集 dts格式 dtb头部结构 dtb标识符 分析具体的文件 title: dtb和dtc文件浅析 date: 2019/4/25 20:09:38 toc: tru ...
- accept:Invalid Argument
错误 #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, ...
- js截取字符串方法整理slice(), substr(), substring(), split()
substr(start,length) stringObject.substr(start,length) //start,截取起始下标,-1 指字符串最后一个字符,-2 指倒数第二个字符开始 ...
- IDEA tomcat 热部署不生效的问题
- 使用 mybatis-generator 自动生成 MyBatis 代码
首先把这三个文件放到一个目录里,我是放到了C盘下的wangbo目录下: 接下来就是设置config.xml文件了,config.xml: <?xml version="1.0" ...
- Swift5 语言指南(十六) 初始化
初始化是准备要使用的类,结构或枚举的实例的过程.此过程涉及为该实例上的每个存储属性设置初始值,并执行在新实例准备好使用之前所需的任何其他设置或初始化. 您可以通过定义实现这个初始化过程初始化,这就像特 ...
- Hybrid App 原理解析
目录 一.现有混合方案 二.Hybrid技术原理 三.Native 通知 H5 (Native 调用 JS) 3.1 Android 调 H5 3.2 iOS 调 H5 四.H5 通知 Native( ...
- Asp.Net Core微信服务中间件-.NetCore2.1
又封周末,闲暇无聊,随手写了一个关于微信公众号服务的中间件,基于.NetCore2.1.服务类库采用.Net Standard2.0,兼容.net 4.6.1. 整体思路是,设计一个中间件,提供微信消 ...
- SQL Server性能优化(15)选择合适的索引
一.关于聚集索引列的选择(参考) 1. 聚集索引所在的列,或者列的组合最好是唯一的. 当我们创建的聚集索引的值不唯一时,SQL Server则无法仅仅通过聚集索引列(也就是关键字)唯一确定一行.此时, ...