Advertisement
bingxuan9112

exactly once common substring

Aug 1st, 2020
1,797
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define debug(x) cerr<<#x<<" = "<<x<<'\n'
  3.  
  4. using namespace std;
  5. const int N = 200025;
  6.  
  7. struct SuffixArray {
  8.     int sa[N], rk[N], nrk[N];
  9.     int H[N];
  10.     int n;
  11.     string S;
  12.     void build(const string &_S) {
  13.         S = _S;
  14.         n = S.size();
  15.         for(int i = 0; i < n; i++) sa[i] = i, rk[i] = S[i];
  16.         for(int L = 1; L < n; L <<= 1) {
  17.             auto cmp = [&](int a, int b) {
  18.                 if(rk[a] != rk[b]) return rk[a] < rk[b];
  19.                 int ra = a+L < n ? rk[a+L] : -1;
  20.                 int rb = b+L < n ? rk[b+L] : -1;
  21.                 return ra < rb;
  22.             };
  23.             sort(sa, sa+n, cmp);
  24.             nrk[0] = 0;
  25.             for(int i = 1; i < n; i++) nrk[i] = nrk[i-1] + cmp(sa[i-1], sa[i]);
  26.             for(int i = 0; i < n; i++) rk[sa[i]] = nrk[i];
  27.         }
  28.         for(int i = 0, h = 0; i < n; i++) {
  29.             if(rk[i] == n-1) continue;
  30.             int j = sa[rk[i]+1];
  31.             while(i+h < n && j+h < n && S[i+h] == S[j+h]) ++h;
  32.             H[rk[i]] = h;
  33.             if(h > 0)
  34.                 --h;
  35.         }
  36.         /* for(int i = 0; i < n; i++) cout << H[i] << ' ' << S.substr(sa[i]) << '\n'; */
  37.     }
  38.     string solve(int k, vector<int> block) {
  39.         vector<bool> cnt(k+1);
  40.         deque<pair<int,int>> dq;
  41.         for(int i = 0, j = 0; i < n; i++) {
  42.             while(cnt[block[sa[i]]]) {
  43.                 cnt[block[sa[j++]]] = false;
  44.                 if(dq.size() && dq.front().second < j) dq.pop_front();
  45.             }
  46.             cnt[block[sa[i]]] = true;
  47.             if(i-j+1 == k && !cnt[k]) {
  48.                 int LCP = dq.front().first; // lcp [j .. i] == min H [j .. i)
  49.                 if((j == 0 || H[j-1] < LCP) && (i == n-1 || H[i+1] < LCP)) {
  50.                     string R = S.substr(sa[j], LCP);
  51.                     return R;
  52.                 }
  53.             }
  54.             while(dq.size() && dq.back().first >= H[i]) dq.pop_back();
  55.             dq.emplace_back(H[i], i);
  56.         }
  57.         return "7122";
  58.     }
  59. } SA;
  60. signed main() {
  61.     ios_base::sync_with_stdio(0), cin.tie(0);
  62.     /* string t; */
  63.     /* cin >> t; */
  64.     /* SA.build(t); */
  65.     /* return 0; */
  66.     int n, tot = 0;
  67.     cin >> n;
  68.     vector<string> v(n);
  69.     for(string &s: v) cin >> s, tot += s.size()+1;
  70.     vector<int> block(--tot);
  71.     string T;
  72.     for(int i = 0, p = 0; i < n; i++) {
  73.         T += v[i];
  74.         while(p < T.size()) block[p++] = i;
  75.         if(i != n-1) T += '$', block[p++] = n;
  76.     }
  77.     SA.build(T);
  78.     cout << SA.solve(n, block) << '\n';
  79. }
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement