[bzoj5285] [HNOI2018]寻宝游戏
Description
某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会。
作为新生的你,对这个活动非常感兴趣。你每天都要从西向东经过教学楼一条很长的走廊,这条走廊是如此的长,以至于它被人戏称为infinite corridor。一次,你经过这条走廊时注意到在走廊的墙壁上隐藏着nn个等长的二进制的数字,长度均为m。你从西向东将这些数字记录了下来,形成一个含有n个数的二进制数组a1,a2,...,an。
很快,在最新的一期的Voo Doo杂志上,你发现了qq个长度也为mm的二进制数r1,r2,...,rq。
聪明的你很快发现了这些数字的含义。
保持数组a_1,a_2,...,a_na1,a2,...,an的元素顺序不变,你可以在它们之间插入∧(按位与运算)或者∨(按位或运算)。例如:11011∧00111=00011,11011∨00111=11111。
你需要插入n个运算符,相邻两个数之前恰好一个,在第一个数的左边还有一个。如果我们在第一个运算符的左边补入一个0,这就形成了一个运算式,我们可以计算它的值。与往常一样,运算顺序是从左到右。有趣的是,出题人已经告诉你这个值的可能的集合——Voo Doo杂志里的那些二进制数r1,r2,...,rq,而解谜的方法,就是对r1,r2,...,rq中的每一个值ri,分别计算出有多少种方法填入这n个计算符,使的这个运算式的值是ri。
然而,infinite corridor真的很长,这意味着数据范围可能非常大。因此,答案也可能非常大,但是你发现由于谜题的特殊性,你只需要求答案模1000000007的值。
Input
第一行三个数n,m,q,含义如题所述。
接下来n行,其中第ii行有一个长度为m的二进制数,左边是最高位,表示ai。
接下来q行,其中第ii行有一个长度为m的二进制数,左边是最高位,表示ri。
Output
输出q行,每行一个数,其中的i行表示对于ri的答案。
Solution
考虑第\(i\)位,显然可以发现,答案一定被最后一个\(\&0\)或者\(|1\)操作所决定,剩下的两个操作对答案并无影响。
然后设操作序列\(s\),操作为\(\&\)时为1,\(|\)时为0。
设每个串的第\(i\)为构成的串为\(t\),
那么比较操作序列\(s\)和\(t\)可得:从后往前数第一个不同的地方决定答案。
然后可以发现这个过程其实就是从后往前比较\(s\)和\(t\)的字典序。
若\(s>t\),则答案为0,否则为1。
所以把\(t\)从大到小排一遍序,对于一个答案序列\(r\),按照\(t\)的位置调整一下,找到第一个0和最后一个1,位置记为\(l,r\)
若\(l<r\),显然没有方案满足,否则操作区间就是\((s(r+1),s(r)]\),所以统计下答案就好了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
const int maxn = 5e3+10;
const int maxm = 2e4+10;
const int mod = 1e9+7;
int n,m,len,rev[maxm],q,tmp[maxn];
char str[maxn][maxm],in[maxn];
struct node{
int a[maxn/30],ans,id;
bool operator < (const node &rhs) const {
for(int i=len;~i;i--) if(a[i]!=rhs.a[i]) return a[i]>rhs.a[i];
return 0;
}
}s[maxm];
int qpow(int a,int x) {
int res=1;
for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod;
return res;
}
signed main() {
read(n),read(m),read(q);len=n/30;
for(int i=1;i<=n;i++) scanf("%s",str[i]+1);
for(int i=1;i<=m;i++) {
for(int j=n;j;j--) {
s[i].a[j/30]=(s[i].a[j/30]<<1)|(str[j][i]-'0');
s[i].ans=(2ll*s[i].ans+str[j][i]-'0')%mod;
}
s[i].id=i;
}
sort(s+1,s+m+1);
s[0].ans=qpow(2,n);
for(int i=1;i<=m;i++) rev[s[i].id]=i;
for(int i=1;i<=q;i++) {
scanf("%s",in+1);int l=0,r=0;
for(int j=1;j<=m;j++) tmp[rev[j]]=in[j]-'0';
for(int j=m;j;j--) if(tmp[j]) {r=j;break;}
for(int j=1;j<=m;j++) if(!tmp[j]) {l=j;break;}
if(l<r&&l&&r) puts("0");
else write(((s[r].ans-s[r+1].ans)%mod+mod)%mod);
}
return 0;
}
[bzoj5285] [HNOI2018]寻宝游戏的更多相关文章
- bzoj千题计划310:bzoj5285: [Hnoi2018]寻宝游戏(思维题+哈希)
https://www.lydsy.com/JudgeOnline/problem.php?id=5285 |0 和 &1 没有影响 若填‘|’,记为0,若填‘&’,记为1 先只考虑最 ...
- 【BZOJ5285】[HNOI2018]寻宝游戏(神仙题)
[BZOJ5285][HNOI2018]寻宝游戏(神仙题) 题面 BZOJ 洛谷 题解 既然是二进制按位的运算,显然按位考虑. 发现这样一个关系,如果是\(or\)的话,只要\(or\ 1\),那么无 ...
- 5285: [Hnoi2018]寻宝游戏
5285: [Hnoi2018]寻宝游戏 链接 分析: 从下面依次确定运算符号,然后在确定的过程中,需要确定的位数会逐渐减少.比如最后有一个1,如果在从下往上确定了一个or 1,那么再往前可以随便选了 ...
- BZOJ.5285.[AHOI/HNOI2018]寻宝游戏(思路 按位计算 基数排序..)
BZOJ LOJ 洛谷 话说vae去年的专辑就叫寻宝游戏诶 只有我去搜Mystery Hunt和infinite corridor了吗... 同样按位考虑,假设\(m=1\). 我们要在一堆\(01\ ...
- bzoj 5285: [Hnoi2018]寻宝游戏
Description Solution 把输入的 \(n\) 个二进制数看作一个大小为 \(n*m\) 的矩阵 把每一列压成一个二进制数,其中最高位是最下面的元素 然后就有了 \(m\) 个二进制数 ...
- HNOI2018寻宝游戏
https://www.luogu.org/problemnew/show/P4424 题解 我们首先按位考虑. 如果有一位最终的结果为1,那么我们可以把树的序列看成一个二进制数,先出现的在底位,后出 ...
- [HNOI2018]寻宝游戏
Description: 给出\(n\)个长为\(m\)的01串,第0个为0,同时给出\(q\)个询问串,每次向其中添加\(n\)个\(\&\)或\(|\)符号,求使这些串按顺序运算得到询问串 ...
- 【比赛】HNOI2018 寻宝游戏
考试的时候就拿了30points滚粗了 听说myy对这题的倒推做法很无奈,官方题解在此 正解思路真的很巧妙,也说的很清楚了 就是分别考虑每一位,会发现题解中的那个性质,然后把询问的二进制数按照排序后的 ...
- [HNOI2018]寻宝游戏(题解转载自别处)
题解(自别处转载): Luogu CSDN 这题关键是将运算符也替换成0,1 然后在运算符与原串混杂里找规律. 而且替换的方式也有所要求,考场上两种替换方式都要尝试. #include <bit ...
随机推荐
- 表单验证(JQ)
<!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...
- js函数的节流和防抖
js函数的节流和防抖 用户浏览页面时会不可避免的触发一些高频度触发事件(例如页面 scroll ,屏幕 resize,监听用户输入等),这些事件会频繁触发浏览器的重拍(reflow)和重绘(repai ...
- 仿制用友U8界面
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- IT类职位常用缩写 SA SD RD PG PM DBA MIS QA Sales
身为IT民工的基本常识,IT类职位常用缩写 SA (System Analyst) 系统分析师 在软体开发团队中,属于中高阶的基层管理者与领导者.除了须具备优秀的文字.语言沟通能力之外,还要有良好的分 ...
- Python学习之魔法方法
Python中会看到前后都加双下划线的函数名,例如 __init__(self),这类写法在Python中具有特殊的含义.如果对象使用了这类方法中的某一个,那么这个方法将会在特殊的情况下被执行,然而几 ...
- CSS3单选动画
本示例实现了两种单选按钮动画效果,一种是缩放,一种是旋转,以下是html布局以及css样式 html:这里使用了label标签的for属性,以此来绑定radio <div class=" ...
- 高德API+Python解决租房问题(.NET版)
源码地址:https://github.com/liguobao/58HouseSearch 在线地址:58公寓高德搜房(全国版):http://codelover.link:8080/ 周末闲着无事 ...
- shell -- shift用法
shift是Unix中非常有用的命令.可以使命令参数左移,从而使脚本程序中命令参数位置不变的情况下依次遍历所有参数.如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1. ...
- Spring MVC - URL路径映射
1. 普通映射 A. @RequestMapping("/test1") B. @RequestMapping(value={"/test1", "/ ...
- jmeter结合autoit操作windows程序
需求: 模拟操作下图软件的控件,如拨号和挂机. 1. 下载安装好autoit后,打开finder tool,使用查找工具定位到要模拟操作的控件上,如图: 2.在finder tool中的control ...