bzoj千题计划310:bzoj5285: [Hnoi2018]寻宝游戏(思维题+哈希)

https://www.lydsy.com/JudgeOnline/problem.php?id=5285

|0 和 &1 没有影响

若填‘|’,记为0,若填‘&’,记为1

先只考虑最后一位

若要求最后=1

那么最后一个|1 要在最后一个 &0 后面

将n个数的最后一位拿出来构成一个01序列

填在所有数最后一位之前的运算符也拿出来构成一个01序列

将第n个数所在位置视为最高位

对于最高位来说

如果数字序列 和 运算符序列 都是0或都是1,没有影响

如果数字序列是0,运算符序列是1,即最后是 &0,显然不能最终等于1,所以这种运算符序列不合法

如果数字序列是1,运算符序列是0,及最后是|1,显然一定是1,这种运算符序列合法

如果数字序列始终等于运算符序列,因为没有影响,所以最终开始开始的那个0,此运算符序列也不合法

所以

如果这一位要求是1,在只考虑这一位的情况下,合法的运算符序列是 运算符的01序列<数字的01序列

同理可以推出

如果这一位要求是0,在只考虑这一位的情况下,合法的运算符序列是 运算符的01序列>=数字的01序列

即可以得到这样的条件:

设合法的运算符序列为S,第i位的数字序列为Ai

若p的第i位为1,则S<Ai  ①

若p的第i位为0,则S>=Ai ②

记①中最小的Ai为 up,②中最大的Ai为down

所以满足所有位的要求的S的个数=up-down

计算个数开始想的是高精减,题目要求取模,直接哈希即可

#include<cstdio>
#include<algorithm>

#define N 5001

using namespace std;

const int mod=1e9+7;

int bit[N];

char s[N];
int has[N];

int sa[N],now[N];

int main()
{
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);
    bit[0]=1;
    for(int i=1;i<=n;++i)
    {
        bit[i]=bit[i-1]<<1;
        bit[i]-=bit[i]>=mod ? mod : 0;
    }
    for(int i=1;i<=m;++i) sa[i]=i;
    int c[2];
    for(int i=1;i<=n;++i)
    {
        c[1]=c[0]=0;
        scanf("%s",s+1);
        for(int j=1;j<=m;++j)
        {
            has[j]=has[j]+(s[j]-‘0‘)*bit[i-1];
            has[j]-=has[j]>=mod ? mod : 0;
            c[s[j]-‘0‘]++;
        }
        c[1]+=c[0];
        for(int j=m;j;--j) now[c[s[sa[j]]-‘0‘]--]=sa[j];
        swap(sa,now);
    }
    int up,down;
    for(int t=1;t<=q;++t)
    {
        up=m+1; down=0;
        scanf("%s",s+1);
        for(int i=1;i<=m && up==m+1;++i)
            if(s[sa[i]]-‘0‘) up=i;
        for(int i=m;i && !down;--i)
            if(!(s[sa[i]]-‘0‘)) down=i;
        if(up<down)
        {
            puts("0");
            continue;
        }
        up= up==m+1 ? bit[n] : has[sa[up]];
        down= !down ? 0 : has[sa[down]];
        printf("%d\n",(up-down+mod)%mod);
    }
}

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8961639.html

时间: 2024-10-11 18:42:46

bzoj千题计划310:bzoj5285: [Hnoi2018]寻宝游戏(思维题+哈希)的相关文章

BZOJ 1968 [Ahoi2005]COMMON 约数研究:数学【思维题】

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1968 题意: 设f(x) = x约数的个数.如:12的约数有1,2,3,4,6,12,所以f(12) = 6. 给定n,问你f(1)到f(n)之和. 题解: 好多做法... (1)O(N*sqrt(N)) 纯暴力(应该过不了). 枚举i,sqrt(i)复杂度求出约数个数,更新ans. 不附代码. (2)O(N*log(N)) 若当前枚举到i,则i为i*k的一个约数(k >= 0),dp[

uoj384 HNOI2018 寻宝游戏

http://uoj.ac/problem/384 这道题有点厉害.. 考虑 \(or\) \(and\) 运算的性质 如果在某一个位置\(and\)上\(0\) 或者 \(or\)上\(1\) 是不是前面的操作都白费了 于是按位考虑 压缩一下状态 以最右边的数作为最高位 设对于位\(i\)的状态是\(b_i\) 操作的序列同样压缩成\(op\) \(or\) 是 \(0\) \(and\) 是 \(1\) (其实只需要建立一个\(and, or\) 和\(bit0, bit1\)的偏序关系就好

BZOJ第一页刷题计划

BZOJ第一页刷题计划 已完成:1 / 100 BZOJ1000:A+B

BZOJ 3208: 花神的秒题计划Ⅰ

3208: 花神的秒题计划Ⅰ Time Limit: 16 Sec  Memory Limit: 128 MBSubmit: 704  Solved: 483[Submit][Status][Discuss] Description 背景[backboard]: Memphis等一群蒟蒻出题中,花神凑过来秒题…… 描述[discribe]: 花花山峰峦起伏,峰顶常年被雪,Memphis打算帮花花山风景区的人员开发一个滑雪项目. 我们可以把风景区看作一个n*n的地图,每个点有它的初始高度,滑雪只能

bzoj 3333: 排队计划 题解

[原题] 3333: 排队计划 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 161  Solved: 71 [Submit][Status] Description Input Output Sample Input 6 2 160 163 164 161 167 160 2 3 Sample Output 6 3 1 HINT Source wyx528命题 [分析]简述一下题目.N个数排成一列,每次指定一个位置P,然后把P~N中所有身高小

屯题计划

感觉lxt一天到晚就是在浪啊浪, 毫无斗志, 颓废得不得了, 每天看小说玩手机到三四点然后整个人都是乱七八糟的. 不行不行我要振作起来了! 从最开始学语言到现在都快两年过去了 T T , 代码能力还是渣成这样简直不能看 T T 觉得应该学学zj爷们屯题. 加油! (题目是直接从劼很久以前的几篇屯题计划里边搬过来的我之前做过的题就删掉了 [BZOJ1822][JSOI2010]Frozen Nova 冷冻波 很水的网络流加计算几何, 然而计算几何部分非常莫名奇妙, 题目应该是判断一个圆是否与一个线

BZOJ 2595 游览计划(插头DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2595 题意:给出一个数字矩阵.求一个连通块包含所有的数字0且连通块内所有数字之和最小. 思路:对于每个格子,是0则必须要选.那么对于不选的格子(i,j)在什么时候可以不选呢?必须同时满足以下两个条件: (1)(i,j)不是0: (2)(i-1,j)不选或者(i-1,j)选了但是轮廓线上还有别的地方与(i-1,j)是一个连通块. int Pre[105][N],op[105][N]; s

2012~2014千日计划总结报告

"一寸光阴一寸金,寸金难买寸光阴."千日计划在时间老人平稳的脚步中,缓缓落幕了.这一次的时光体验让我看到了一个浓缩版的自己,感谢上苍赐予我一个最真实的自己,让我为自己日后走什么样的路奠定了决策基础. 综合评定而言,结果和期望有一定的落差,这或许就是梦想与现实的距离.也许在现实生活中就是这样,很多人都死在了好高骛远的旅途中,想法不接地气,导致在日后的人生旅途中越走越窄,越发觉得外部环境对自己的不公,从而产生一些无厘头的抱怨和嗔恨. 我应该感到庆幸,通过自己一分一秒的践行后,看到了这一切-

【BZOJ】【3991】【SDOI2015】寻宝游戏

dfs序 我哭啊……这题在考试的时候(我不是山东的,CH大法吼)没想出来……只写了50分的暴力QAQ 而且苦逼的写的比正解还长……我骗点分容易吗QAQ 骗分做法: 1.$n,m\leq 1000$: 直接找一个关键点做根进行深搜,算出其他关键点都与root连通的最小边权和,再×2 2.一条链的情况:用set维护序列中哪些点选了,然后ans=(sum[tail]-sum[head])*2; 其中sum[i]表示从序列首到第 i 个的边长之和……嗯就是前缀和优化一下= =取首和尾这一段的Len之和