3508. Longest Common Substring

Powered by:NEFU AB-IN

Link

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;
    }
    

Guess you like

Origin blog.csdn.net/qq_45859188/article/details/130272387