洛谷P4424 [HNOI/AHOI2018]寻宝游戏 题解
Posted 。✧* ꧁王者꧂✧*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P4424 [HNOI/AHOI2018]寻宝游戏 题解相关的知识,希望对你有一定的参考价值。
题面
不得不说,这真的是一道二进制好题!!!
思路转换得极其精妙,看得我不禁连连叫好!!!
一般看到类似的与二进制运算符有关的题目,按位进行肯定是首要考虑的。
我们考虑在按位进行二进制运算时的性质:
从上图可以看出,当运算符是
∣
|
∣且下一位数字是
1
1
1时,结果一定是
1
1
1;当运算符是&且下一位是
0
0
0时,结果一定是
0
0
0。
从上图可以看出,当运算符是
∣
|
∣且下一位是
0
0
0时,值不发生改变;当运算符是&且下一位是
1
1
1时,值不发生改变。
那么,试想,如果我们用
0
0
0和
1
1
1分别表示
∣
|
∣和&,那么,一个操作序列
o
p
op
op,就可以用二进制表示了。这有什么用呢?
把对应的
o
p
op
op序列与上图的性质进行对比,你会发现,当
o
p
op
op的数与进行操作的数相同时,对结果不造成影响;不同时,会被操作的数覆盖原先值。比如:
00
对
应
∣
0
00对应|0
00对应∣0,
10
对
应
10对应
10对应&
0
0
0。
接下来,我们考虑当多个
0
0
0和
1
1
1进行二进制运算时,结果为
1
1
1和结果为
0
0
0时,对应的操作序列的特征。
显然,
o
p
op
op序列与
01
01
01序列对应位置相同时,当前位置不对结果造成影响,所以,我们只用考虑
01
01
01和
10
10
10就行了,前者将值覆盖为1,后者将值覆盖为0,为使结果为1,我们要保证最后一个
01
01
01后不出现
10
10
10,也就是说,最后一个
01
01
01后的每一位都相同。这样的话,将
o
p
op
op序列和
01
01
01序列翻转过来,那么
01
01
01序列对应的二进制数大于
o
p
op
op序列。
同理,你会发现,当结果为0时,
01
01
01序列的二进制数小于等于
o
p
op
op序列的二进制数。
于是,这道题就变成了比大小。每给出一个
a
n
s
ans
ans,根据每一个位置上是
0
0
0还是
1
1
1,求出最终的答案区间。
为了保证时间复杂度,我们要先对
m
m
m个长度为
n
n
n的二进制序列从小到大排序。这在输入的同时就可以操作。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10 , p = 1e9 + 7;
int n , m , Q , ra[N] , la[N] , a[N] , ans[N] , b[N][1001];
char s[N];
int main()
{
cin >> n >> m >> Q;
for(int i = 1;i <= m; i++)
ra[i] = i;
for(int i = 1; i <= n; i++)
{
scanf("%s" , s + 1);
for(int j = 1; j <= m; j++)
{
a[j] = s[j] - '0';
b[j][i] = a[j];
}
int cnt = 0;
for(int j = 1; j <= m; j++)
if(a[ra[j]] == 0) la[++cnt] = ra[j];
for(int j = 1; j <= m; j++)
if(a[ra[j]] == 1) la[++cnt] = ra[j];
for(int j = 1; j <= m; j++)
ra[j] = la[j];
}
for(int i = 1; i <= m ; i++)
{
for(int j = n; j >= 1; j--)
{
ans[i] = (2ll * ans[i] + b[i][j]) % p;
}
}
for(int i = 1; i <= n; i++)
ans[m+1] = (2ll * ans[m+1] + 1) % p;
ra[m+1] = m + 1;
ans[m+1] += 1;
while(Q--)
{
scanf("%s" , s + 1);
int L = 0 , R = m + 1;
for(int i = 1 ; i <= m; i++)
if(s[ra[i]]=='1')
{
R = i;
break;
}
for(int i = m; i >= 1; i--)
{
if(s[ra[i]]=='0')
{
L = i;
break;
}
}
printf("%d\\n",R < L? 0 : (ans[ra[R]] - ans[ra[L]] + p) % p);
}
return 0;
}
以上是关于洛谷P4424 [HNOI/AHOI2018]寻宝游戏 题解的主要内容,如果未能解决你的问题,请参考以下文章