题解-Reachable Strings

前置知识:

\(\texttt{Hash}\)


Reachable Strings

给一个长度为 \(n\) 的 \(\texttt{01}\) 串 \(s\),可以让 \(s\) 中的 \(\texttt{110}\) 和 \(\texttt{011}\) 互相转换。\(q\) 次询问,每次给定两个 \(s\) 的子串 \(s_{l_1\sim l_1+len-1}\) 和 \(s_{l_2\sim l_2+len-1}\),问两个串是否可以互相变换得到。

数据范围:\(1\le n,q\le 10^5\)。


哈希萌新觉得这是哈希好题。


很容易注意到 \(\texttt{11}\color{#9c3}{\texttt{0}}\leftrightarrow\color{#9c3}{\texttt{0}}\texttt{11}\) 就是 \(\texttt{0}\) 左右移动两个位置。

但是不可以 \(\texttt{10}\color{#9c3}{\texttt{0}}\leftrightarrow\color{#9c3}{\texttt{0}}\texttt{01}\) 或 \(\texttt{01}\color{#9c3}{\texttt{0}}\leftrightarrow\color{#9c3}{\texttt{0}}\texttt{10}\),说明 \(\texttt{0}\) 移动时不能跨越别的 \(\texttt{0}\)。

综上,所有 \(\texttt{0}\) 的位置(从左往右第几个 \(\texttt{0}\)) 不会发生改变,并且下标的奇偶性不会变。

所以可以把所有 \(\texttt{0}\) 按序记录下标奇偶性生成序列,然后判断 两个子序列 是否可以互相变换得到 可以用序列哈希对比 看是否相等。

重点是因为每个子序列的起点奇偶性不都相同,所以每个 \(0\) 有两种奇偶性可能,所以用两个哈希数组。


具体实现哈希时可以用一个质数进制数来表示一个序列。

如果从高到低第 \(i\) 位为 \(1\),就表示原字符串从左到右第 \(i\) 个 \(\texttt{0}\) 的下标为奇数;如果为 \(2\),就表示原字符串从左到右第 \(i\) 个 \(\texttt{0}\) 的下标为偶数。

然后开前缀 \(\texttt{0}\) 序列数组 \(h\),\(h_n\) 表示原字符串前 \(n\) 个 \(\texttt{0}\) 哈希得的质数进制数。

因为子序列的起点奇偶性不同,所以有两个 \(h\),分别表示以起点为奇数和偶数为标准时哈希得的前缀 \(\texttt{0}\) 序列数组。

子串可以由前缀 \(\texttt{0}\) 序列数组推得,看是否可以互相变换得到只需直接比较子串。

但是有个问题:\(0\) 那么多,形成的质数进制数太大怎么办(远爆 \(\texttt{long long}\))?

解决方法是模某个大质数(如 \(998244353\))。虽然这样可能会把两个不同的序列哈希得一样,但这正是哈希的精髓。没有绝对正确的哈希,能解决问题的就是好哈希。


Code

#include <bits/stdc++.h>
using namespace std; //&Start
#define inf 0x3f3f3f3f
#define re register
#define il inline
#define hash unorded_map
typedef long long lng;
typedef unsigned long long ulng;
typedef vector<int> veci;
#define fo(i,st,xb,y) for(re int i=st;i xb;i y) //&Data
#define N 200000
#define mod 998244353 //模数为998244353
#define base 5119 //5119进制
char s[N+10];
int n,m,h[N+10][2],bs[N+10]={1},ze[N+10];
//两个h,进制前缀积,零数量前缀和 //&Main
il int Hash(re int l,re int r,re int o){return (-1ll*h[l-1][o]*bs[ze[r]-ze[l-1]]%mod+h[r][o]+mod)%mod;} //子序列哈希值
int main(){
scanf("%d%s",&n,s+1);
fo(i,1,<=n,++)
if(s[i]=='1') h[i][0]=h[i-1][0],h[i][1]=h[i-1][1],ze[i]=ze[i-1];
else h[i][0]=(1ll*h[i-1][0]*base%mod+1+(i&1))%mod,
h[i][1]=(1ll*h[i-1][1]*base%mod+1+((i&1)^1))%mod,ze[i]=ze[i-1]+1;
fo(i,1,<=n,++) bs[i]=1ll*bs[i-1]*base%mod;
scanf("%d",&m); fo(i,1,<=m,++){
re int l1,l2,len; scanf("%d%d%d",&l1,&l2,&len);
(Hash(l1,l1+len-1,l1&1)==Hash(l2,l2+len-1,l2&1)?puts("Yes"):puts("No"));
}
return 0;
}

祝大家学习愉快!

题解-Reachable Strings的更多相关文章

  1. CF1320 Div1 D.Reachable Strings 题解

    题目大意 给定一个长为\(n\)的01串\(S\),每次你可以对一个串的三个连续位置做:\(011 \rightarrow 110\),\(110 \rightarrow 011\)的操作. 有\(q ...

  2. 【Virt.Contest】CF1321(div.2)

    第一次打虚拟赛. CF 传送门 T1:Contest for Robots 统计 \(r[i]=1\) 且 \(b[i]=0\) 的位数 \(t1\) 和 \(r[i]=0\) 且 \(b[i]=1\ ...

  3. Codeforces Round #625 (1A - 1D)

      A - Journey Planning 题意: 有一列共 n 个城市, 每个城市有美丽值 b[i], 要访问一个子序列的城市, 这个子序列相邻项的原项数之差等于美丽值之差, 求最大的美丽值总和. ...

  4. 题解-ARC058D Iroha Loves Strings

    题面 ARC058D Iroha Loves Strings 给定 \(n\) 个字符串,从中选出若干个按给出顺序连接起来,总长等于 \(m\),求字典序最小的,保证有解. 数据范围:\(1\le n ...

  5. [LeetCode]题解(python):043-Multiply Strings

    题目来源 https://leetcode.com/problems/multiply-strings/ Given two numbers represented as strings, retur ...

  6. 【题解】Power Strings

    题目描述 给定若干个长度小于等于10^6的字符串,询问每个字符串最多由多少个相同的子串重复连接而成.如:ababab,最多由3个ab连接而成. 输入输出格式 输入格式 若干行,每行一个字符串. 当读入 ...

  7. Power Strings[poj2406]题解

    Power Strings Description - Given two strings a and b we define ab to be their concatenation. For ex ...

  8. CF1144A Diverse Strings 题解

    Content 我们定义一个字符串是合法的,当且仅当这个字符串是"连续排列"(按照字母表顺序排序).现在给出 \(n\) 个字符串 \(s_1,s_2,s_3,...,s_n\), ...

  9. POJ 2406 Power Strings KMP运用题解

    本题是计算一个字符串能完整分成多少一模一样的子字符串. 原来是使用KMP的next数组计算出来的,一直都认为是能够利用next数组的.可是自己想了非常久没能这么简洁地总结出来,也仅仅能查查他人代码才恍 ...

随机推荐

  1. JS 实现飞机大战

    这是JS版本的飞机大战,和C#版本的思路相同,就是语言上有差别,用来巩固知识.可以将代码直接引入到HTML中就可以看到效果 //编写背景对象 function Background(width,hei ...

  2. docker生产——容器通信

    简介 在接触docker的第一天起,大家应该就知道:docker容器使用沙箱机制,相互之间没有接口,一般情况下内部访问通过IP+端口.本地容器默认分配的IP极易发生变化,所以靠IP+端口访问的方式缺失 ...

  3. vdbench测试实时可视化显示

    前言 前一段时间碰到一个系统,用rados bench 去跑都还比较正常,但是一跑数据库就非常慢,测试工具会抛出延时过大的提示,经过排查发现,云平台中有一台虚拟机还运行着备份数据库的服务,而这个备份软 ...

  4. Linux ---搭建SFTP服务器

    在Centos 6.6环境使用系统自带的internal-sftp搭建SFTP服务器. 打开命令终端窗口,按以下步骤操作. 0.查看openssh的版本 ssh -V 使用ssh -V 命令来查看op ...

  5. 【Python】Json序列化和反序列化模块dumps、loads、dump、load函数介绍

    1.json.dumps()  json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. 转换案例: ...

  6. classmethod、staticclassmethod内置装饰器函数

    # method 英文是方法的意思 # classmethod 类方法 # 当一个类中的方法中只涉及操作类的静态属性时,此时在逻辑上,我们想要直接通过类名就可以调用这个方法去修改类的静态属性,此时可以 ...

  7. Spring扩展之一:ApplicationContextInitializer

    1.介绍 用于Spring容器ConfigurableApplicationContext在刷新之前初始化Spring的回调接口. 通常在需要对应用程序上下文进行一些编程初始化的Web应用程序中使用. ...

  8. Linux权限位(含特殊权限位s s t) 及chown\chmod命令使用

    1.普通权限位 ls –l查看文件的属性 [root@oldboy ~]# ls -l -rw-------. 1 root root 1073 Mar 4 22:08 anaconda-ks.cfg ...

  9. [head first 设计模式] 第一章 策略模式

    [head first 设计模式] 第一章 策略模式 让我们先从一个简单的鸭子模拟器开始讲起. 假设有个简单的鸭子模拟器,游戏中会出现各种鸭子,此系统的原始设计如下,设计了一个鸭子超类,并让各种鸭子继 ...

  10. Web安全常见漏洞修复建议

    转载地址:https://security.pingan.com/blog/17.html SQL注入 在服务器端要对所有的输入数据验证有效性. 在处理输入之前,验证所有客户端提供的数据,包括所有的参 ...