欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - 51Nod1753


题意概括

  两个字符串相似定义为:

  1.两个字符串长度相等
  2.两个字符串对应位置上有且仅有至多一个位置所对应的字符不相同

  给定一个字符串,每次询问两个子串在给定的规则下是否相似。给定的规则指每次给出一些等价关系,如‘a'=’b',‘b'=’c'等,注意这里的等价关系具有传递性,即若‘a'=’b',‘b'=’c',则‘a'=’c'。


题解

  我们弄一个可以通过前缀求得区间某一个字母的排列的哈希。

  然后判断两个字符串是否相等,就是把该区间所有的字母的哈希值整合起来。

  具体看代码。

  然后就是二分。

  如果两个串完全相等,那么YES。

  我们二分,取一个mid,对于mid来说:

  如果 左串1≠左串2 且 右串1≠右串2,那么可以确定是NO了。

  否则 如果 左串1≠左串2,那么继续弄左串,否则继续弄右串。

  时间复杂度:N*26*logN ≈ 1e8而且常数较大。

  但是时限有5s,所以可以过去。


代码

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int L=300000+5;
LL p=233333333,mod=1000000007,Inv=474576274;
int n,m,a[L],fa[26];
LL ha[L][26],Pow[L];
char str[L];
int getf(int k){
return fa[k]==k?k:fa[k]=getf(fa[k]);
}
LL gethash(int L,int R){
LL Hash=0;
for (int i=0;i<26;i++){
LL x=(ha[R][i]+mod-ha[L-1][i]*Pow[R-L+1]%mod)%mod;
Hash=(Hash+x*(getf(i)+1))%mod;
}
return Hash;
}
int main(){
scanf("%s",str);
n=strlen(str);
Pow[0]=1;
for (int i=1;i<=n;i++)
Pow[i]=Pow[i-1]*p%mod;
for (int i=1;i<=n;i++)
a[i]=str[i-1]-'a';
// 注意,这里只是对于同一个字母的哈希。最后在汇总的时候,要乘上(字母值+1)防止0的出现。
memset(ha,0,sizeof ha);
for (int i=1;i<=n;i++){
for (int j=0;j<26;j++)
ha[i][j]=ha[i-1][j]*p%mod;
ha[i][a[i]]=(ha[i][a[i]]+1)%mod;
}
scanf("%d",&m);
while (m--){
int k,L1,R1,L2,R2;
scanf("%d%d%d%d%d",&k,&L1,&R1,&L2,&R2);
for (int i=0;i<26;i++)
fa[i]=i;
for (int i=1;i<=k;i++){
char ch[5];
scanf("%s",ch);
fa[getf(ch[0]-'a')]=getf(ch[1]-'a');
}
if (R1-L1+1!=R2-L2+1){
puts("NO");
continue;
}
if (gethash(L1,R1)==gethash(L2,R2)){
puts("YES");
continue;
}
bool flag=1;
int le=1,ri=R1-L1+1,mid;
while (le<ri){
mid=(le+ri)>>1;
LL haL1=gethash(L1+le-1,L1+mid-1);
LL haL2=gethash(L2+le-1,L2+mid-1);
LL haR1=gethash(L1+mid,L1+ri-1);
LL haR2=gethash(L2+mid,L2+ri-1);
if (haL1!=haL2&&haR1!=haR2){
flag=0;
break;
}
if (haL1!=haL2)
ri=mid;
else
le=mid+1;
}
puts(flag?"YES":"NO");
}
return 0;
}

  

51Nod 算法马拉松28 B题 相似子串 哈希的更多相关文章

  1. 51Nod 算法马拉松28 C题 栈 单调队列

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - 51Nod1952 题意概括 有一个栈,有3种操作: Ο 从栈顶加入一个元素 Ο 从栈底加入一个元素 Ο 从栈 ...

  2. 51Nod 算法马拉松28 A题 先序遍历与后序遍历 分治

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - 51Nod1832 题意概括 对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的二叉树. 两棵二 ...

  3. 51NOD 算法马拉松8

    题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...

  4. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  5. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  6. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  7. 51Nod 算法马拉松22 开黑记

    这是一场惨烈的开黑大战,始于全机房开黑指望刷进rank前十拿钱的壮志,终于被各路神犇怒踩成rank20,差点200点头盾不保的落魄,想起将近一年前ad和zcg等学长挤进rank10的壮举,不由得唏嘘, ...

  8. 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

    OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...

  9. 51Nod 算法马拉松23 开黑记

    惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...

随机推荐

  1. Java图片比对

    在自动化测试中,除了普通的值验证,经常还有一些图片验证,比如图片的匹配率,输出图片的差异图片等.本文主要用到了BufferedImage类来操作图片比对和输出差异图片,大体的思路如下: 1. 通过Im ...

  2. 算法排序【时间复杂度O(n^2)】

    排序算法的两个原则: 1.输出结果为递增或者递减. 2.输出结果为原输入结果的排列或者重组. 平均时间复杂度为O(n^2)的排序算法有三种: 冒泡排序,插入排序,选择排序. 一.冒泡排序: 即谁冒泡泡 ...

  3. KillerBee

    KillerBee介绍 KillerBee----是攻击zigbee和IEEE 802.15.4网络的框架和工具.使用killerBee工具和一个兼容的IEEE 802.15.4无线接口,你就能窃取z ...

  4. CSS——超链接颜色设置

    <!-- 链接颜色 --> a:link { color:#FF0000; text-decoration:underline; } a:visited { color:#00FF00; ...

  5. new和delete

    和 sizeof 类似,sizeof不是函数,它是一个操作符,它在编译期就完成了计算,在函数运行期间它已经是一个常数值了. int a; sizeof(int) = 4; sizeof(a) = 4; ...

  6. [转]mmap和madvise的使用

    1.    madvise的简介            madvise可以设置内存的分配方式或者说是分配的细节方式.具体参见linux man madvise. #include <sys/ty ...

  7. Maven入门-运行struts项目进行测试(三)

    maven运行struts项目进行测试: 在入门二中已经导入struts的jar包. 此时的pom.xml文件 <project xmlns="http://maven.apache. ...

  8. javascript随笔和常见的知识点

    1.js中循环中用 return只能停止循环,不能停止到函数的定义部分.所以下面的返回值为1 return 100没有意义,只起到终止循环的目的 function bb() { var sum = 0 ...

  9. activit流程引擎启动流程报错

    代码如下: 目录结构 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); @Test public void ...

  10. zabbix常见报错问题处理

    ①报错: zabbix_agentd [20529]: cannot create Semaphore: [28] No space left on device zabbix_agentd [205 ...