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 ...
随机推荐
- Poj 2304 Combination Lock(模拟顺、逆时钟开组合锁)
一.题目大意 模拟一个开组合的密码锁过程.就像电影你开保险箱一样,左转几圈右转几圈的就搞定了.这个牌子的锁呢,也有它独特的转法.这个锁呢,有一个转盘,刻度为0~39.在正北方向上有一个刻度指针.它的密 ...
- HDOJ1213(并查集)
set容器中的值互异,非常好用. 水题,直接贴代码了 #include<iostream> #include<cstdio> #include<set> using ...
- Velocity常用标签的讲解
Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象. 当Veloci ...
- ios判断是否为iphone6或iphone6plus代码
转自:http://blog.csdn.net/lvxiangan/article/details/45288505 #define IS_IPAD (UI_USER_INTERFACE_IDIOM( ...
- AngularJs(Part 11)--自定义Directive
先对自定义Directive有一个大体的映像 myModule.directive('myDirective',function(injectables){ var directiveDefiniti ...
- Eclipse插件——EasyExplore安装
Eclipse插件--EasyExplore安装 分类: eclipse2011-12-07 09:02 458人阅读 评论(0) 收藏 举报 插件功能 easyexplore是一个eclipse的小 ...
- 阶段2-新手上路\项目-移动物体监控系统\Sprint1-声音报警子系统开发\第1节-Sprint Backlog规划
根据之前的sprint1-声音报警子系统是相对比较大的一个需求,需要把它进一步细化,然后指定sprint Backlog product Backlog是整个产品的功能列表! sprint Backl ...
- change和onchange、click和onclick的区别
change和onchange.click和onclick的区别: onchange和onclick都是js方法 可以在标签元素上使用 <input onchange="" ...
- Web 应用之数据库的配置 与链接 Mysql
source 绝对路径.sql(绝对路径是对应数据库版本包下的) source时是有先后顺序的必须是create 在insert 在 下面是链接,上面是把数据导入到数据库中,数据也可以自己写进去. 配 ...
- 关于.net Core项目发布在Linux上的填坑
本文主要记录.net Core项目发布在Linux服务器上面所遇到的问题,防止遗忘是 1.在发布文件中执行 dotnet xxxxxx.dll的时候提示如下错误: An assembly specif ...