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. OIer应该知道的二进制知识

    计算机使用\(2\)进制,这是众所周知的.在学习\(OI\)的过程中,\(2\)进制也显得尤为重要.有时候,细节决定成败,所以我想总结一下容易被遗忘和误解的关于\(2\)进制的知识. 1.运算符 &a ...

  2. bzoj 2850 巧克力王国——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2850 改一下估价即可.判断子树能否整个取或者是否整个不能取,时间好像就能行了? 因为有负数, ...

  3. 【转】 Pro Android学习笔记(六五):安全和权限(2):权限和自定义权限

    目录(?)[-] 进程边界 声明和使用权限 AndroidManifestxml的许可设置 自定义权限 运行安全通过两个层面进行保护.进程层面:不同应用运行在不同的进程,每个应用有独自的user ID ...

  4. web攻击之四:DOS攻击

    DDOS是DOS攻击中的一种方法. DoS:是Denial of Service的简称,即拒绝服务,不是DOS操作系统,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务. ...

  5. WPF Canvas

    Canvas为容器控件,用于定位. 1.基本应用 <Border HorizontalAlignment="Left" VerticalAlignment="Top ...

  6. IO系列之File

    1 File类 1.1 目录列表器 在这里我主要是参考Think in Java的内容从而做的一些总结以及扩展.Java中的IO流的设计应该说是Java中最经典的,最学院式的设计,包括它的整体架构设计 ...

  7. Spring开发包介绍

    -----------------siwuxie095                         核心开发包         建立 Spring 工程时,需要引入 Spring 的开发包,否则无 ...

  8. 初始String

    --------------siwuxie095                             使用频繁操作繁琐的数据有哪些?                 对于基本数据类型:int.ch ...

  9. 8、泛型程序设计与c++标准模板库5.函数对象

    1.函数对象 函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性.大多数STL算法可以用一个函数对象作为参数.所谓“函数对象”其实就是一个行为类似函数的对象, ...

  10. c++中Int装string

    java中,string类型非常强大,任何类型和string类型相加都变成了string类型.但是c++中string功能就比较少 int转string有两种方式 1:stringstream; ; ...