POJ-2774 字符串哈希+二分

题意:给出s,t两个字符串,求最长公共子串的长度

思路:首先二分答案x,预处理出s中长度为x的子串哈希值并排序,在t中枚举起点,二分查找t[i...i+x]的哈希值

二分查找直接用binary_search()函数

复杂度其实是nlog方

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define LL long long
 6 #define uLL unsigned long long
 7 #define debug(x) cout << "[" << x << "]" << endl
 8 using namespace std;
 9
10 const int mx = 1e5+10;
11 const int base = 131;
12 char s[mx], t[mx];
13 uLL hs[mx], ht[mx], a[mx], p[mx];
14 int n, m;
15
16 bool check(int x){
17     int cnt = 0;
18     for (int i = x; i <= n; i++)
19         a[cnt++] = hs[i]-p[x]*hs[i-x];
20     sort(a, a+cnt);
21     for (int i = x; i <= m; i++){
22         uLL k = ht[i]-p[x]*ht[i-x];
23         if (binary_search(a, a+cnt, k)) return 0;
24     }
25     return 1;
26 }
27
28 int main(){
29     p[0] = 1;
30     scanf("%s%s", s+1, t+1);
31     n = strlen(s+1), m = strlen(t+1);
32     for (int i = 1; i <= n; i++) hs[i] = hs[i-1]*base+s[i]-‘a‘;
33     for (int i = 1; i <= m; i++) ht[i] = ht[i-1]*base+t[i]-‘a‘;
34     for (int i = 1; i <= max(n, m); i++) p[i] = p[i-1]*base;
35     int l = 0, r = min(n, m);
36     while (l <= r){
37         int mid = (l+r)>>1;
38         if (check(mid)) r = mid-1;
39         else l = mid+1;
40     }
41     printf("%d\n", r);
42     return 0;
43 }

原文地址:https://www.cnblogs.com/QAQorz/p/9733818.html

时间: 2024-10-04 03:08:11

POJ-2774 字符串哈希+二分的相关文章

POJ 2774 字符串哈希_解题报告

题目:  http://poj.org/problem?id=2774 A - Long Long Message The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is getting ill. Being worried about spending so much on railway ticke

poj 2774 字符串哈希求最长公共子串

Long Long Message #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <stack> #include <cmath> #include <map> #include <string&

【CodeForces】961 F. k-substrings 字符串哈希+二分

[题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} \right \rceil]$,找到满足[奇数长度][严格子串][同时是前缀和后缀]的最长子串.n<=10^6. [算法]字符串哈希+二分 [题解]任意两个对应子串,它们有一个不变量--它们的中心一定是i和n-i+1.而且固定中心之后,能延伸的最长相等子串是可以二分+哈希得到的. 所以枚举k,二分+

poj 2774 最长公共子串--字符串hash或者后缀数组或者后缀自动机

http://poj.org/problem?id=2774 想用后缀数组的看这里:http://blog.csdn.net/u011026968/article/details/22801015 本文主要讲下怎么hash去找 开始的时候写的是O(n^2 logn)算法 果断超时...虽然也用了二分的,, 代码如下: //hash+二分 #include <cstdio> #include <cstring> #include <algorithm> #include

字符串哈希专题

layout: post title: 字符串哈希专题 author: "luowentaoaa" catalog: true tags: mathjax: true - 字符串 传送门 A.POJ - 1200 A - Crazy Search 摘要 哈希进制转换 题意 一个字符串分成长度为N的字串.且不同的字符不会超过NC个.问总共有多少个不同的子串 思路 以nc作为进制,把一个子串化为这个进制下的数,再用哈希判断 #include<cstdio> #include&l

POJ 2774 Long Long Message (最长公共子串)

Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 27062   Accepted: 11010 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days

POJ 2774 后缀数组:求最长公共子串

思路:其实很简单,就是两个字符串连接起来,中间用个特殊字符隔开,然后用后缀数组求最长公共前缀,然后不同在两个串中,并且最长的就是最长公共子串了. 注意的是:用第一个字符串来判断是不是在同一个字符中,刚开始用了第二个字符的长度来判断WA了2发才发现. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<

[POJ 2774] Long Long Message 【后缀数组】

题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符串分别的一个后缀的 LCP ,并且这两个后缀在 SA 中一定是相邻的. 那么他们的 LCP 就是 Height[i] ,当然,Height[i] 的最大值不一定就是 LCS ,因为可能 SA[i] 和 SA[i-1] 是在同一个字符串中. 那么判断一下,如果 SA[i] 与 SA[i - 1] 分别

Long Long Message POJ - 2774

Long Long Message POJ - 2774 题意:求两个串的最长公共字串. 用特殊符号连接两个字符串,后缀数组. 枚举height,如果sa[i]和sa[i-1]分别属于不同的串,则更新最大值. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn