标签:Hash int 题解 Long maxn long ull const include
题意:求最长公共子串
思路:把两个串Hash,然后我们把短的作为LCS的最大可能值,然后二分长度,每次判断这样二分可不可以。判断时,先拿出第一个母串所有len长的子串,排序,然后枚举第二个母串len长度字串,二分查找在第一个母串的子串中存不存在。
代码:
#include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 100000 + 10; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 1000000007; ull hs[maxn], hp[maxn], fac[maxn], q[maxn]; int len1, len2; char s[maxn], p[maxn]; ull get_hash(ull *h, int l, int r){ return h[r] - h[l - 1] * fac[r - l + 1]; } bool check(int len){ int cnt = 0; for(int i = 1; i + len - 1 <= len1; i++){ q[cnt++] = get_hash(hs, i, i + len - 1); } sort(q, q + cnt); for(int i = 1; i + len - 1 <= len2; i++){ ull aim = get_hash(hp, i, i + len - 1); if(binary_search(q, q + cnt, aim)) return true; } return false; } int main(){ fac[0] = 1; for(int i = 1; i < maxn; i++) fac[i] = fac[i - 1] * seed; while(~scanf("%s%s", s + 1, p + 1)){ len1 = strlen(s + 1); len2 = strlen(p + 1); hs[0] = hp[0] = 0; for(int i = 1; i <= len1; i++) hs[i] = hs[i - 1] * seed + (s[i] - 'a'); for(int i = 1; i <= len2; i++) hp[i] = hp[i - 1] * seed + (p[i] - 'a'); int l = 0, r = min(len1, len2); int ans = 0; while(l <= r){ int m = (l + r) >> 1; if(check(m)){ l = m + 1; ans = m; } else{ r = m - 1; } } printf("%d\n", ans); } return 0; }
标签:Hash,int,题解,Long,maxn,long,ull,const,include 来源: https://www.cnblogs.com/KirinSB/p/10662817.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。