http://acm.hdu.edu.cn/showproblem.php?pid=5069

首先判断suffix和prefix最长多少可以直接暴力枚举长度然后 + hash可以立马判断是否相等,复杂度O(lenstr)

现在知道总长度 <= 1e5,  magic = sqrt(lenstr)

那么,

如果长度是 <= magic的,最多1e5个询问,每次询问我暴力也是才1e5 * sqrt(1e5)的复杂度。

如果长度是 >= magic的,

第一个极端情况是有magic个不同的串,这样就可以有magic^2个不同的询问,但是这样每个串的长度最长是magic,这样暴力也是才magic * magic * magic  = 1e5 * sqrt(1e5)的复杂度。

第二个极端情况是只有2个串,每个串长度都很长,1e5 / 2 的长度,这样暴力一次就需要O(1e5)的复杂度了。但是如果这样的话,不同的询问就会很少,可以用个ans数组存起来,ans[a][b],这样总复杂度也是 <= 1e5 * sqrt(1e5)的复杂度。

所以总复杂度是nsqrtn

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e5 + ;
char str[maxn];
int po[maxn], suffix[maxn], prefix[maxn];
int be[maxn], en[maxn];
int n, q;
int ans[][];
int getAns(int one, int two) {
for (int i = min(en[two] - be[two] + , en[one] - be[one] + ); i >= ; --i) {
if (prefix[be[two] + i - ] == suffix[en[one] - i + ]) {
return i;
}
}
return ;
}
int pos[maxn];
void work() {
scanf("%d%d", &n, &q);
int magic = (int)sqrt(n * 1.0);
int to = ;
for (int i = ; i <= n; ++i) {
scanf("%s", str + en[i - ] + );
int len = strlen(str + en[i - ] + );
be[i] = en[i - ] + , en[i] = en[i - ] + len;
prefix[be[i]] = str[be[i]];
for (int j = be[i] + ; j <= en[i]; ++j) {
prefix[j] = prefix[j - ] * + str[j];
}
suffix[en[i]] = str[en[i]];
for (int j = en[i] - ; j >= be[i]; --j) {
suffix[j] = str[j] * po[en[i] - j] + suffix[j + ];
}
if (len > magic) {
pos[i] = ++to;
}
}
// printf("%s\n", str + 1);
// for (int i = 1; i <= n; ++i) {
// printf("%d %d\n", be[i], en[i]);
// }
for (int i = ; i <= to; ++i) {
for (int j = ; j <= to; ++j) {
ans[i][j] = -;
}
}
while (q--) {
int one, two;
scanf("%d%d", &one, &two);
if (en[one] - be[one] + <= magic || en[two] - be[two] + <= magic) {
printf("%d\n", getAns(one, two));
} else {
if (ans[pos[one]][pos[two]] == -) {
ans[pos[one]][pos[two]] = getAns(one, two);
}
printf("%d\n", ans[pos[one]][pos[two]]);
}
}
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
po[] = ;
for (int i = ; i <= maxn - ; ++i) po[i] = po[i - ] * ;
while (scanf("%d%d", &n, &q) > ) work();
return ;
}

https://www.nowcoder.com/acm/contest/94/E

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef unsigned long long int LL;
const int maxn = 1e6 + ;
char str[maxn];
LL po[maxn], suffix[maxn], prefix[maxn];
int be[maxn], en[maxn];
int n, q;
int ans[][];
int getAns(int one, int two) {
for (int i = min(en[two] - be[two] + , en[one] - be[one] + ); i >= ; --i) {
if (prefix[be[two] + i - ] == suffix[en[one] - i + ]) {
return i;
}
}
return ;
}
int pos[maxn];
void work() {
int magic = (int)sqrt( * 1.0);
int to = ;
for (int i = ; i <= n; ++i) {
scanf("%s", str + en[i - ] + );
int len = strlen(str + en[i - ] + );
be[i] = en[i - ] + , en[i] = en[i - ] + len;
prefix[be[i]] = str[be[i]];
for (int j = be[i] + ; j <= en[i]; ++j) {
prefix[j] = prefix[j - ] * + str[j];
}
suffix[en[i]] = str[en[i]];
for (int j = en[i] - ; j >= be[i]; --j) {
suffix[j] = str[j] * po[en[i] - j] + suffix[j + ];
}
if (len > magic) {
pos[i] = ++to;
}
}
// printf("%s\n", str + 1);
// for (int i = 1; i <= n; ++i) {
// printf("%d %d\n", be[i], en[i]);
// }
for (int i = ; i <= to; ++i) {
for (int j = ; j <= to; ++j) {
ans[i][j] = -;
}
}
cin >> q;
while (q--) {
int one, two;
scanf("%d%d", &one, &two);
if (en[one] - be[one] + <= magic || en[two] - be[two] + <= magic) {
printf("%d\n", getAns(one, two));
} else {
if (ans[pos[one]][pos[two]] == -) {
ans[pos[one]][pos[two]] = getAns(one, two);
}
printf("%d\n", ans[pos[one]][pos[two]]);
}
}
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
po[] = ;
for (int i = ; i <= maxn - ; ++i) po[i] = po[i - ] * ;
while (scanf("%d", &n) > ) work();
return ;
}

Harry And Biological Teacher 分块 + 字符串hash的更多相关文章

  1. HDU 5763 Another Meaning dp+字符串hash || DP+KMP

    题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe   sub:hehe 那么,有**he.he** ...

  2. [知识点]字符串Hash

    1.前言 字符串的几大主要算法都多少提及过,现在来讲讲一个称不上什么算法, 但是非常常用的东西——字符串Hash. 2.Hash的概念 Hash更详细的概念不多说了,它的作用在于能够对复杂的状态进行简 ...

  3. 【BZOJ-3555】企鹅QQ 字符串Hash

    3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1545  Solved: 593[Submit][Statu ...

  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. 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

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

  8. 字符串hash - POJ 3461 Oulipo

    Oulipo Problem's Link ---------------------------------------------------------------------------- M ...

  9. 长度有限制的字符串hash函数

    长度有限制的字符串hash函数 DJBHash是一种非常流行的算法,俗称"Times33"算法.Times33的算法很简单,就是不断的乘33,原型如下 hash(i) = hash ...

随机推荐

  1. 洛谷【P1601】A+B Problem(高精)

    题目传送门:https://www.luogu.org/problemnew/show/P1601 高精度加法板子.我们灵性地回忆一波小学学加法列竖式的场景(从\(6\)岁开始口算从未打过草稿的大佬请 ...

  2. I2C Bus

    概述: I²C 是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or "eye-two-cee" , 它是一 ...

  3. JavaScript编写代码时候没有提示

    如上图所示如果没有提示可能是箭头所指示的类型不正确.

  4. JavaScript-Tool:pluload

    ylbtech-JavaScript-Tool:pluload Plupload是用于处理文件上传的JavaScript API,支持多文件选择.文件类型过滤.请求分块.客户端图像缩放等功能,使用不同 ...

  5. 测试-Swagger:目录

    ylbtech-测试-Swagger:目录 1.返回顶部 1. https://swagger.io/ 2.Swagger Editor http://swagger.io/swagger-edito ...

  6. linux strace-跟踪进程的系统调用或是信号产生情况,lstrace-跟踪己丑年调用库函数情况,进程跟踪调试命令

    本工具可以用来做大多数排除,比如mount一个NFS,很慢,找不出原因,我们可以使用strace命令来跟中mount这个经常所有的调用过程. strace 命令是一种强大的工具,它能够显示所有由用户空 ...

  7. 快速实现CentOS7安装python-pip

    1.首先检查linux有没有安装python-pip包,终端执行 pip -V [root@ network-scripts]# pip -V -bash: pip: command not foun ...

  8. 如何从光盘本地安装CentOS 7图形界面(Gnome GUI)

    本例中通过在CentOS 7中修改repo文件,直接从光盘或者ISO镜像文件安装Gnome图形界面(Gnome GUI),从而避免耗时从官网或镜像下载. 1.首先确保光盘或者ISO镜像文件正确连接到客 ...

  9. Linux部署walle

    背景:Walle 一个web部署系统工具,配置简单.功能完善.界面流畅.开箱即用!支持git.svn版本管理,支持各种web代码发布,PHP,Python,JAVA等代码的发布.回滚,可以通过web来 ...

  10. free查看内存情况

    free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区. free [option]     -b:以Byte为单位显示内存使用情况:      -k:以KB为单位显 ...