Harry And Biological Teacher 分块 + 字符串hash
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的更多相关文章
- HDU 5763 Another Meaning dp+字符串hash || DP+KMP
题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe sub:hehe 那么,有**he.he** ...
- [知识点]字符串Hash
1.前言 字符串的几大主要算法都多少提及过,现在来讲讲一个称不上什么算法, 但是非常常用的东西——字符串Hash. 2.Hash的概念 Hash更详细的概念不多说了,它的作用在于能够对复杂的状态进行简 ...
- 【BZOJ-3555】企鹅QQ 字符串Hash
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1545 Solved: 593[Submit][Statu ...
- POJ 1200 字符串HASH
题目链接:http://poj.org/problem?id=1200 题意:给定一个字符串,字符串只有NC个不同的字符,问这个字符串所有长度为N的子串有多少个不相同. 思路:字符串HASH,因为只有 ...
- LA4671 K-neighbor substrings(FFT + 字符串Hash)
题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...
- 各种字符串Hash函数比较(转)
常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- 字符串hash - POJ 3461 Oulipo
Oulipo Problem's Link ---------------------------------------------------------------------------- M ...
- 长度有限制的字符串hash函数
长度有限制的字符串hash函数 DJBHash是一种非常流行的算法,俗称"Times33"算法.Times33的算法很简单,就是不断的乘33,原型如下 hash(i) = hash ...
随机推荐
- 无密码登录Linux服务器
1.使用windows上的SecureCRT生成密钥对. Tools->Create Public Key..->RSA->Passphrase(最好输入,也可为空)->长度默 ...
- C#SqlDataReader的用法
string sqljn = "select [序号],[品名],[电压等级],[单位],[型号],[规格],[红本价格] FROM [book].[dbo].[View_wjprice]& ...
- node.js的国内源
node.js在使用npm安装包是,由于源是国外的,有可能会被GFW屏蔽. 通过下面的方法可以把源指向国内的. 具体方法如下: 编辑 ~/.npmrc 加入下面内容 registry = http:/ ...
- Python知识点: os.popen
用例:f = os.popen("%s %s %s" % ("pkg-config", " ".join(args), mod)) pope ...
- springMVC绑定json参数之二(2.1)
二.springmvc 接收不同格式的json字符串 1.首先扫盲几个知识点: 这个绑定json参数讲的都是用@RequestBody标签,所以前台必须传json字符串,不能是json对象,但是如果不 ...
- LAMP 2.0Apache日志切割
每次访问网站就会产生若干条日志,当然前提是已经配置了日志. 配置日志的文件在 vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 把注释掉的这两行打 ...
- Delegate Action<T in> Func<T in,out Tresult> Predicate<T>
action<T> 和 func<T> 都是delegate的简写形式,其中T为可以接受的参数类型 action<T> 指那些只有输入参数,没有返回值 Deleg ...
- C语言学习笔记--void关键字
1.C语言中Void关键字的含义 void 修饰函数返回值和参数——为了表示“无”,如果函数没有返回值,那么应该将其声明为 void,同样的,如果函数没有参数,也应该声明其参数为 void //f() ...
- ubuntu下root用户默认密码及修改方法
[ubuntu下root用户默认密码及修改方法] 很多朋友用ubuntu,一般都是装完ubuntu系统,马上就修改root密码了,那么root用户的默认密码是多少,当忘记root用户密码时如何找回呢, ...
- 杭电acm 1032题
The Problem问题 Consider the following algorithm:考虑下面的算法: 1 2 3 4 5 6 input n print n if n = 1 then st ...