Loj #2494. 「AHOI / HNOI2018」寻宝游戏

题目描述

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

作为新生的你对这个活动非常感兴趣。你每天都要从西向东经过教学楼一条很长的走廊,这条走廊是如此的长,以至于它被人戏称为 infinite corridor。一次,你经过这条走廊的时,注意到在走廊的墙壁上隐藏着 \(n\) 个等长的二进制的数字,长度均为 \(m\)。你从西向东将这些数字记录了下来,形成一个含有 \(n\) 个数的二进制数组 \(a_1, a_2, ..., a_n\)。很快,在最新的一期 Voo Doo 杂志上,你发现了 \(q\) 个长度也为 \(m\) 的二进制串 \(r_1, r_2, ..., r_q\)。聪明的你很快发现了这些数字的含义。保持数组 \(a_1, a_2, ..., a_n\) 的元素顺序不变,你可以在它们之间插入 \(\wedge\)(按位与运算)或者 \(\vee\)(按位或运算)两种二进制运算符。例如:\(11011 \wedge 00111=00011,11011 \vee 00111=11111\)。

你需要插入恰好 \(n\) 个运算符,相邻两个数之间恰好一个,在第一个数的左边还有一个。如果我们在第一个运算符的左边补入一个 \(0\),这就形成了一个运算式,我们可以计算它的值。与往常一样,运算顺序是从左往右。有趣的是,出题人已经告诉你这个值的可能的集合——Voo Doo 杂志里的那一些二进制数 \(r_1, r_2, ..., r_q\),而解谜的方法,就是对 \(r_1, r_2, ..., r_q\) 中的每一个值 \(r_i\),分别计算出有多少种方法填入这 \(n\) 个运算符,使得这个运算式的值是 \(r_i\) 。然而,infinite corridor 真的很长,这意味着数据范围可能非常大。因此,答案也可能非常大,但是你发现由于谜题的特殊性,你只需要求答案模 \(1000000007\)(\(10^9 + 7\),一个质数)的值。

输入格式

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

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

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

输出格式

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

数据范围与提示

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

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

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

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

\(\\\)

\(myy\)的题就是神仙啊!

首先我们对每一位单独考虑,再将\(m\)位的一起考虑。

我们将操作序列也定义为一个\(01\)串。如果是\(and\)操作,则为\(1\),否则为\(0\)。

我们发现:

\[x\ and\ 0=0\\
x\ or\ 1=1
\]

也就是说\(\ and\ 0\)和\(\ or\ 1\)本质上是赋值操作。

然后

\[x\ and\ 1=x\\
x\ or\ 0=x
\]

也就是说\(\ and\ 1\)和\(\ or\ 0\)后上值不变。

然后考虑第\(j\)位,如果它应该为\(1\),则最后一个赋值操作后第\(j\)位变成了\(1\)。然后我们观察操作序列和第\(j\)列的\(01\)串之间的关系。赋值操作的时候对应位置上的数不同。所以,我们以\(n\)为最高位,设第\(j\)列的数字为\(s_j\),操作序列的数字为\(R\),则\(R>s_j\)。

反之,则\(R\leq s_j\)。

所以我们将\(m\)列数字排序过后找到上下界就行了。

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define N 1005
  4. #define M 5005
  5. using namespace std;
  6. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  7. const ll mod=1e9+7;
  8. int n,m,q;
  9. char a[N][M],r[M];
  10. ll pw2[M];
  11. int len;
  12. const ll maxx=1<<30;
  13. int rk[M];
  14. struct node {
  15. int id;
  16. ll val[50];
  17. bool operator <(const node &x)const {
  18. for(int i=len;i>=1;i--) if(val[i]!=x.val[i]) return val[i]<x.val[i];
  19. return id<x.id;
  20. }
  21. }s[M];
  22. node operator -(node a,node b) {
  23. for(int i=1;i<=len;i++) {
  24. if(a.val[i]<b.val[i]) {
  25. a.val[i+1]--;
  26. a.val[i]+=maxx;
  27. }
  28. a.val[i]-=b.val[i];
  29. }
  30. return a;
  31. }
  32. ll bin[N];
  33. int main() {
  34. n=Get(),m=Get(),q=Get();
  35. pw2[0]=1;
  36. for(int i=1;i<=n;i++) pw2[i]=pw2[i-1]*2%mod;
  37. for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
  38. len=(n-1)/30+1;
  39. for(int i=1;i<=m;i++) s[i].id=i;
  40. for(int j=n;j>=1;j--) {
  41. int now=(j-1)/30+1;
  42. for(int i=1;i<=m;i++) {
  43. s[i].val[now]=(s[i].val[now]<<1)|(a[j][i]-'0');
  44. }
  45. }
  46. sort(s+1,s+1+m);
  47. for(int i=1;i<=m;i++) rk[s[i].id]=i;
  48. for(int i=1;i<=n;i++) {
  49. int now=(i-1)/30+1;
  50. s[m+1].val[now]=(s[m+1].val[now]<<1)|1;
  51. }
  52. for(int i=1;i<len;i++) bin[i]=i*30;
  53. bin[len]=bin[len-1]+(n-1)%30+1;
  54. s[0].id=0,s[m+1].id=m+1;
  55. int tim=0;
  56. while(q--) {
  57. scanf("%s",r+1);
  58. int lx=0,rx=m+1;
  59. for(int i=1;i<=m;i++) {
  60. if(r[i]=='1') rx=min(rx,rk[i]);
  61. else lx=max(lx,rk[i]);
  62. }
  63. if(lx>=rx) cout<<0<<"\n";
  64. else {
  65. ll ans=0;
  66. node c=s[rx]-s[lx];
  67. for(int i=1;i<=len;i++) (ans+=c.val[i]*pw2[bin[i-1]])%=mod;
  68. if(rx==m+1) ans=(ans+1)%mod;
  69. cout<<ans<<"\n";
  70. }
  71. }
  72. return 0;
  73. }

Loj #2494. 「AHOI / HNOI2018」寻宝游戏的更多相关文章

  1. 【LOJ】#2494. 「AHOI / HNOI2018」寻宝游戏

    题面 题解 第\(i\)个数之前的符号是或那么记为0,是与就记为1,得到一个二进数x 然后按位分开考虑,如果这一行是1那么记为1,如果这一位数位0记为0,得到一个二进制数\(b_i\) 第\(N\)行 ...

  2. Loj #2495. 「AHOI / HNOI2018」转盘

    Loj #2495. 「AHOI / HNOI2018」转盘 题目描述 一次小 G 和小 H 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1 ...

  3. loj #2508. 「AHOI / HNOI2018」游戏

    #2508. 「AHOI / HNOI2018」游戏 题目描述 一次小 G 和小 H 在玩寻宝游戏,有 nnn 个房间排成一列,编号为 1,2,…,n,相邻房间之间都有 111 道门.其中一部分门上有 ...

  4. loj #2510. 「AHOI / HNOI2018」道路

    #2510. 「AHOI / HNOI2018」道路 题目描述 W 国的交通呈一棵树的形状.W 国一共有 n−1 个城市和 nnn 个乡村,其中城市从 111 到 n−1 编号,乡村从 111 到 n ...

  5. loj #2509. 「AHOI / HNOI2018」排列

    #2509. 「AHOI / HNOI2018」排列   题目描述 给定 nnn 个整数 a1,a2,…,an(0≤ai≤n),以及 nnn 个整数 w1,w2,…,wn.称 a1,a2,…,an 的 ...

  6. @loj - 2496@ 「AHOI / HNOI2018」毒瘤

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的 ...

  7. loj#2510. 「AHOI / HNOI2018」道路 记忆化,dp

    题目链接 https://loj.ac/problem/2510 思路 f[i][a][b]表示到i时,公路个数a,铁路个数b 记忆化 复杂度=状态数=\(nlog^2n\) 代码 #include ...

  8. loj#2509. 「AHOI / HNOI2018」排列(思维题 set)

    题意 题目链接 Sol 神仙题Orz 首先不难看出如果我们从\(a_i\)向\(i\)连一条边,我们会得到以\(0\)为根的树(因为每个点一定都有一个入度,出现环说明无解),同时在进行排列的时候需要保 ...

  9. loj#2020 「AHOI / HNOI2017」礼物 ntt

    loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...

随机推荐

  1. SLAM入门之视觉里程计(1):特征点的匹配

    SLAM 主要分为两个部分:前端和后端,前端也就是视觉里程计(VO),它根据相邻图像的信息粗略的估计出相机的运动,给后端提供较好的初始值.VO的实现方法可以根据是否需要提取特征分为两类:基于特征点的方 ...

  2. JDBC驱动程序注册 JDBC简介(二)

    使用JDBC进行数据库操作的第一步就是驱动注册(当然你得先导入JAR). 驱动注册有多种方式,第一步必然是获得正确的驱动名称与URL格式 驱动名称与URL格式 RDBMS 驱动程序名称        ...

  3. Java提高班(六)反射和动态代理(JDK Proxy和Cglib)

    反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多.要怎么理解以上这句话,请看下文. 一.反射 反射机制是 Ja ...

  4. SpringBoot整合系列-整合H2

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959855.html SpringBoot整合H2内存数据库 一般我们在测试的时候习惯于 ...

  5. RabbitMQ是如何运转的?

    前言 之前已经介绍了RabbitMQ交换机模型的相关简单概念,都是作为此篇的基础铺垫,如果对此篇不懂的可以先看我上一篇的介绍认识RabbitMQ交换机模型,或者联系评论,分享<RabbitMQ实 ...

  6. Java学习笔记之——多线程

    多线程编程 程序: 进程:一个程序运行就会产生一个进程 线程:进程的执行流程,一个进程至少有一个线程,称为主线程 如:QQ聊着天,同时在听音乐 一个进程可以有多个线程,多个线程共享同一个进程的资源 线 ...

  7. 纯CSS实现点击事件展现隐藏div菜单列表/元素切换

    在写移动端导航的时候经常用到点击按钮出现/隐藏导航条的情况,最常见的方法当然还是前端框架直接调用,省心省力,不易出错:当然还有使用纯JS实现的小代码段.我这里整理了纯CSS实现方式,给需要的人和给自己 ...

  8. vue2.x 下载后台传过来的流文件(excel)后乱码问题

    1.接口返回的流和头部: 2.下载流文件的代码 方法一:是用了插件 https://github.com/kennethjiang/js-file-download 方法二:是用了 blob 不管哪种 ...

  9. SAP MM 可以不用创建盘点凭证直接录入盘点结果?

    SAP MM 可以不用创建盘点凭证直接录入盘点结果? 可以.SAP标准功能就支持这么做. 事务代码 MI09 (Enter Count w/o Reference to Document), 输入pl ...

  10. 使用Python下载工具you-get下载媒体文件

    You-Get是一个基于 Python 3 的下载工具.使用 You-Get 可以很轻松的下载到网络上的视频.图片及音乐. 使用you-get下载媒体文件 1.安装Python(步骤详情见另一篇文章) ...