Powered by:NEFU AB-IN
Article directory
3508. Longest Common Substring
-
title meaning
Given two strings, find the length of the longest common substring of these two strings that does not contain numbers.
-
train of thought
First of all, you can use dp method to do it violently, and the complexity is O ( n 2 ) O(n^2)O ( n2 )
Second, consider the dichotomy, because the answer is monotonous, so you can store the hash value of a string whose length is mid in the hash table during dichotomy, and judge whether there is no number in the end when scanninganother
stringThis one, you can replace the numbers in each string with different symbols -
the code
#include <bits/stdc++.h> using namespace std; #define int long long #undef int #define ULL unsigned long long #define SZ(X) ((int)(X).size()) #define ALL(X) (X).begin(), (X).end() #define IOS \ ios::sync_with_stdio(false); \ cin.tie(nullptr); \ cout.tie(nullptr) #define DEBUG(X) cout << #X << ": " << X << '\n' typedef pair<int, int> PII; const int N = 1e5 + 10, INF = 0x3f3f3f3f, P = 13331; ULL hs[N], ps[N], ht[N], pt[N]; string s, t; ULL gets(int l, int r) { return hs[r] - hs[l - 1] * ps[r - l + 1]; } ULL gett(int l, int r) { return ht[r] - ht[l - 1] * pt[r - l + 1]; } bool check(int x) { unordered_set <int> us; for(int i = 1; i + x - 1 < SZ(s); ++ i){ us.insert(gets(i, i + x - 1)); } for(int i = 1; i + x - 1 < SZ(t); ++ i){ if(us.count(gett(i, i + x - 1))) return true; } return false; } signed main() { IOS; cin >> s >> t; s = " " + s; t = " " + t; for(int i = 1; i < SZ(s); ++ i){ if(s[i] >= '0' && s[i] <= '9') s[i] = '#'; } for(int i = 1; i < SZ(t); ++ i){ if(t[i] >= '0' && t[i] <= '9') t[i] = '$'; } ps[0] = pt[0] = 1; for(int i = 1; i < SZ(s); ++ i){ ps[i] = ps[i - 1] * P; hs[i] = hs[i - 1] * P + s[i]; } for(int i = 1; i < SZ(t); ++ i){ pt[i] = pt[i - 1] * P; ht[i] = ht[i - 1] * P + t[i]; } int l = 0, r = min(SZ(s), SZ(t)); while(l < r){ int mid = l + r + 1 >> 1; if(check(mid)) l = mid; else r = mid - 1; } cout << r; return 0; }