Seek the Name, Seek the Fame (字符串hash)

mac2022-06-30  23

Seek the Name, Seek the Fame (字符串hash)

poj-2752题目描述 给定若干只含小写字母的字符串(这些字符串总长≤400000),在每个字符串中求出所有既是前缀又是后缀的子串长度。

例如:ababcababababcabab,既是前缀又是后缀的子串:ab,abab,ababcabab,ababcababababcabab。

输入格式 输入若干行,每行一个字符串。

输出格式 对于每个字符串,输出一行,包含若干个递增的整数,表示所有既是前缀又是后缀的子串长度。

样例输入 ababcababababcabab aaaaa alala nucacm样例输出 2 4 9 18 1 2 3 4 5 1 3 5 6

思路

直接套字符串hash。 计算原字符串的hash。然后枚举长度,判断 前 len 的长度的字符串hash和后 len 长度的字符串hash是否相同。相同就输出len.

#include <iostream> #include <algorithm> #include <map> #include <vector> #include <cstdio> #include <cstring> using namespace std; #define N 1000090 #define base 161 typedef unsigned long long ull; ull p[N], hs[N]; char str[N]; ull gethash(int l, int r) { return hs[r] - p[r - l + 1] * hs[l - 1]; } void cal() { hs[0] = 0; int len = strlen(str + 1); for (int i = 1; i <= len; i++) hs[i] = hs[i - 1] * base + str[i]; } void slove() { cal(); int len = strlen(str + 1); int res = 0, f = 0; for (int i = 1; i <= len; i++) { if (gethash(1, 1 + i - 1) == gethash(len - i + 1, len)) if (!f) { cout << i; f = 1; } else cout << " " << i; } cout << endl; } int main() { p[0] = 1; for (int i = 1; i <= N; i++) p[i] = p[i - 1] * base; while (scanf("%s", str + 1) != EOF) { slove(); } }

转载于:https://www.cnblogs.com/tttfu/p/11344702.html

最新回复(0)