1735  相似子串 
基准时间限制:5 秒 空间限制:131072 KB 分值: 80
 
两个字符串相似定义为:
1.两个字符串长度相等
2.两个字符串对应位置上有且仅有至多一个位置所对应的字符不相同
给定一个字符串,每次询问两个子串在给定的规则下是否相似。给定的规则指每次给出一些等价关系,如‘a'=’b',‘b'=’c'等,注意这里的等价关系具有传递性,即若‘a'=’b',‘b'=’c',则‘a'=’c'。
Input
第一行一个字符串s(1<=|s|<=300000)
第二行一个整数T(1<=T<=300000)
对于每次询问:
第一行5个整数k,l1,r1,l2,r2,表示有k个等价规则,询问的是子串[l1,r1],[l2,r2](1<=k<=10,1<=l1<=r1<=|s|,1<=l2<=r2<=|s|)
接下来k行每行两个连续的字符表示这两个字符等价。
此题中所有的字符均为小写字母。
Output
T行,若相似则输出“YES”否则输出“NO”
Input示例
abac
3
1 1 2 3 4
bc
1 1 2 3 4
ac
1 1 2 2 3
ac
Output示例
 
YES
YES
NO
题解:
  hash值是由一系列字符* base^i 组成的,这里首先按照字母归类(如“aba”,按“a”归类即为“a”*( base^1+base^3 ))
  如果只是判断在给定规则下是否相等,那么可以把归类后26个字母对应的hash值按照并查集里的等价关系进行累加,

    若某一联通块所对应的hash值的总和在两个串中不相等则两个串在给定规则下不相等,否则相等。
   考虑只有一个位置不同的情况,那么必然是存在两个联通块对应的hash在两个串上不相等,且这两个差值是base的某个幂次的两个相反数,
  那么预处理一下base所有次幂并存下即可。
  时间复杂度O((|S|+T)*26)
#include <bits/stdc++.h>
inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}
using namespace std;
typedef unsigned long long ULL; const int N = 4e5+;
const ULL mod = 10000019ULL; ULL sqr[N], tmp = , pre[N][], fi[], se[];
map<ULL, int> mp;
char s[N], ch[];
int T, fa[], vis[], F[];
int finds(int x) {return fa[x] == x? x:fa[x]=finds(fa[x]);}
int main() {
scanf("%s%d",s+,&T);
int n = strlen(s+);
sqr[] = ;
for(int i = ; i <= n; ++i) sqr[i] = sqr[i-] * mod, mp[sqr[i]] = ,mp[(-sqr[i])] = ;
for(int i = ; i <= n; ++i) {
tmp = tmp * mod;
pre[i][s[i] - 'a' + ] += tmp;
}
for(int i = ; i <= n; ++i) {
for(int j = ; j <= ; ++j) pre[i][j] += pre[i-][j];
}
for(int t = ; t <= T; t++) {
int k,l1,r1,l2,r2,cnt = ;
scanf("%d%d%d%d%d",&k,&l1,&r1,&l2,&r2);
for(int i = ; i <= ; ++i) fa[i] = i,vis[i] = ;
for(int i = ; i <= ; ++i) fi[i] = pre[r1][i] - pre[l1-][i];
for(int i = ; i <= ; ++i) se[i] = pre[r2][i] - pre[l2-][i];
for(int i = ; i <= k; ++i) {
scanf("%s",ch);
int fx = finds(ch[] - 'a' + );
int fy = finds(ch[] - 'a' + );
if(fx > fy) swap(fx,fy);
if(fx != fy)
fa[fy] = fx,fi[fx] += fi[fy],se[fx] += se[fy],fi[fy] = ,se[fy] = ;
}
if(r1 - l1 != r2 - l2) {
printf("NO\n");
continue;
}
for(int i = ; i <= ; ++i) {
int nfa = finds(i);
if(fi[nfa]*sqr[l2 - l1] != se[nfa] && !vis[nfa])
F[++cnt] = i, vis[nfa] = ;
}
if(cnt == ) printf("YES\n");
else {
if(cnt > ) printf("NO\n");
else {
if(fi[F[]]*sqr[l2 - l1] + fi[F[]]*sqr[l2 - l1]== se[F[]] + se[F[]]) {
if(mp[(fi[F[]]*sqr[l2 - l1] - se[F[]])])printf("YES\n");
else printf("NO\n");
}
else printf("NO\n");
}
}
}
return ;
}

51 NOD 1753 相似子串 字符串hash的更多相关文章

  1. 51 Nod 1092 回文字符串

    1092 回文字符串  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每 ...

  2. 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

    Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...

  3. AcWing:139. 回文子串的最大长度(字符串Hash + 前缀和 + 后缀和 + 二分)

    如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...

  4. POJ 1200 字符串HASH

    题目链接:http://poj.org/problem?id=1200 题意:给定一个字符串,字符串只有NC个不同的字符,问这个字符串所有长度为N的子串有多少个不相同. 思路:字符串HASH,因为只有 ...

  5. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

  6. 各种字符串Hash函数比较(转)

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  7. hdu 4622 Reincarnation 字符串hash 模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同 ...

  8. [转]各种字符串Hash函数比较

    转自:https://www.byvoid.com/zht/blog/string-hash-compare 常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些 ...

  9. 【转】各种字符串Hash函数比较

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

随机推荐

  1. bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳

    题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...

  2. MySQL 源码编译安装

    脚本须知: 1. 该脚本目前只测试过mysql版本为5.6.x的源码,其他源码可以对本脚本稍作修改即可 2. 本脚本也可以使用wget mysql源码的方式进行,但考虑到后期提供源码的地址不可用,所以 ...

  3. ThinkPHP 5.1 基础知识

    ==========================================//模板中的默认标题{$title|default='默认标题'}========================= ...

  4. HDU 6206 Apple

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6206 判断给定一点是否在三角形外接圆内. 给定三角形三个顶点的坐标,如何求三角形的外心的坐标呢? 知乎 ...

  5. Java原来如此-随机数

    在Java中,生成随机数有两种方法.1是使用Random类.2是使用Math类中的random方法. 我们现在做个例子,比如生成20个0到10之间的随机数. 1.使用Random类的nextInt(n ...

  6. 深入理解js中的立即执行函数(function(){…})()

    javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ( f ...

  7. restful的认识和用法

    目录 一.restful的认识 1.基本概念 2.规范和约束 3.使用标准的状态码 二.具体使用 1.简单概括 2.根据id查询一个员工 3.查询所有员工 4.保存一个员工 5.根据id修改员工 6. ...

  8. 查询和设置mysql事务隔离级别

    1.查看当前会话隔离级别 select @@tx_isolation; 2.查看系统当前隔离级别 select @@global.tx_isolation; 3.设置当前会话隔离级别 set sess ...

  9. jquery 全选获取值

    首选区分一下prop与attr的差别.prop是固有属性,attr自定义属性. $("#all").click(function () {//全选.反选 if(this.check ...

  10. Unix domain socket

    转载:http://www.cnblogs.com/chekliang/p/3222950.html socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是 ...