bingxuan9112

Untitled

Aug 23rd, 2021
1,223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.16 KB | None | 0 0
  1. // An AC a day keeps the doctor away.  #pragma GCC optimize("Ofast")
  2. #include <bits/stdc++.h>
  3. #ifdef local
  4. #define safe std::cerr<<__PRETTY_FUNCTION__<<" line "<<__LINE__<<" safe\n"
  5. #define debug(args...) qqbx(#args, args)
  6. #define orange(args...) danb(#args, args)
  7. #define INFO(msg) qqbx(msg, "")
  8. using std::cerr;
  9. template <typename ...T> void qqbx(const char *s, T ...args) {
  10.     int cnt = sizeof...(T);
  11.     ((cerr << "\e[1;32m(" << s << ") = ("), ..., (cerr << args << (--cnt ? ", " : ")\e[0m\n")));
  12. }
  13. template <typename T> void danb(const char *s, T L, T R) {
  14.     cerr << "\e[1;32m[ " << s << " ] = [ ";
  15.     for (int f = 0; L != R; ++L) cerr << (f++ ? ", " : "") << *L;
  16.     cerr << " ]\e[0m\n";
  17. }
  18. #else
  19. #define safe ((void)0)
  20. #define debug(...) ((void)0)
  21. #define orange(...) ((void)0)
  22. #define INFO(...) ((void)0)
  23. #endif // local
  24. #define all(v) begin(v),end(v)
  25.  
  26. using namespace std;
  27. const int maxn = 200025;
  28. const int inf = 1e9;
  29.  
  30. struct RMQ {
  31.     vector<int> st[20];
  32.     template <typename T>
  33.     void build(T L, T R) {
  34.         st[0].assign(L, R);
  35.         int n = st[0].size();
  36.         for (int L = 1; L < 20; L++) {
  37.             st[L].resize(n);
  38.             int len = 1 << (L - 1);
  39.             for (int i = 0; i + len * 2 <= n; i++) {
  40.                 st[L][i] = min(st[L-1][i], st[L-1][i + len]);
  41.             }
  42.         }
  43.     }
  44.     int query(int l, int r) {
  45.         if (l == r) return inf;
  46.         // [l, r)
  47.         int lev = __lg(r - l), len = 1 << lev;
  48.         return min(st[lev][l], st[lev][r - len]);
  49.     }
  50. };
  51.  
  52. struct SuffixArray {
  53.     vector<int> sa, rk, hei;
  54.     RMQ rmq;
  55.     SuffixArray(const string &s) : sa(s.size()), rk(s.size()), hei(s.size()) {
  56.         int n = s.size();
  57.         for (int i = 0; i < n; i++) {
  58.             sa[i] = i;
  59.             rk[i] = s[i];
  60.         }
  61.         for (int L = 1; L < n; L <<= 1) {
  62.             auto cmp = [&](int a, int b) {
  63.                 if (rk[a] != rk[b])
  64.                     return rk[a] < rk[b];
  65.                 int ra = a+L < n ? rk[a+L] : -1;
  66.                 int rb = b+L < n ? rk[b+L] : -1;
  67.                 return ra < rb;
  68.             };
  69.             sort(sa.begin(), sa.end(), cmp);
  70.             vector<int> nrk(n);
  71.             nrk[sa[0]] = 0;
  72.             for (int i = 1; i < n; i++)
  73.                 nrk[sa[i]] = nrk[sa[i-1]] + cmp(sa[i-1], sa[i]);
  74.             rk = nrk;
  75.         }
  76.  
  77.         for (int i = 0, h = 0; i < n; i++) {
  78.             if (!rk[i]) {
  79.                 h = 0;
  80.                 continue;
  81.             }
  82.             int j = sa[rk[i]-1];
  83.             while (i+h < n && j+h < n && s[i+h] == s[j+h]) ++h;
  84.             hei[rk[i]] = h;
  85.             if (h > 0) --h;
  86.         }
  87.         debug(s);
  88.         orange(all(sa));
  89.         orange(all(hei));
  90.         orange(all(rk));
  91.         rmq.build(hei.begin(), hei.end());
  92.     }
  93.     int query(int l, int r) {
  94.         assert (l < r);
  95.         return rmq.query(l+1, r+1);
  96.     }
  97. };
  98.  
  99. int pa[maxn], sz[maxn];
  100. int anc(int x) {
  101.     return x==pa[x] ? x : pa[x]=anc(pa[x]);
  102. }
  103. set<int> stA[maxn], stB[maxn];
  104. signed main() {
  105.     ios_base::sync_with_stdio(0), cin.tie(0);
  106.     string A, B;
  107.     cin >> A >> B;
  108.  
  109.     auto reversed = [](string s) {
  110.         reverse(all(s));
  111.         return s;
  112.     };
  113.     string T = "$$" + A + "##" + B + "&&";
  114.     SuffixArray SA(T);
  115.     SuffixArray rSA(reversed(T));
  116.  
  117.     vector<int> ord(T.size() - 1);
  118.     iota(all(ord), 1);
  119.     sort(all(ord), [&rSA](int x, int y) { return rSA.hei[x] > rSA.hei[y]; });
  120.  
  121.     for (int i = -1; i+1 < (int)A.size(); i++) {
  122.         int j = i + 2;
  123.         stA[rSA.rk[T.size() - 1 - j]].insert(SA.rk[j+2]);
  124.     }
  125.     for (int i = -1; i+1 < (int)B.size(); i++) {
  126.         int j = i + A.size() + 4;
  127.         stB[rSA.rk[T.size() - 1 - j]].insert(SA.rk[j+2]);
  128.     }
  129.  
  130.     auto getMaxLCP = [&SA, &rSA, &T](set<int> &st, int x) {
  131.         pair<int,int> res(-inf, -inf);
  132.         auto it = st.lower_bound(x);
  133.         if (it != st.begin())
  134.             res = max(res, make_pair(SA.query(*prev(it), x), *prev(it)));
  135.         if (it != st.end())
  136.             res = max(res, make_pair(SA.query(x, *it), *it));
  137.         return res;
  138.     };
  139.  
  140.     tuple<int,int,int> ans(-inf, -inf, -inf);
  141.     auto join = [&getMaxLCP, &SA, &ans](int x, int y, int h) {
  142.         x = anc(x);
  143.         y = anc(y);
  144.         assert (x != y);
  145.         if (sz[x] < sz[y]) swap(x, y);
  146.  
  147.         for (int p: stA[y]) {
  148.             auto [l, q] = getMaxLCP(stB[x], p);
  149.             if (q != -inf)
  150.                 ans = max(ans, make_tuple(h + l + 1, SA.sa[p] - h - 1, SA.sa[q] - h - 1));
  151.         }
  152.         for (int p: stB[y]) {
  153.             auto [l, q] = getMaxLCP(stA[x], p);
  154.             if (q != -inf)
  155.                 ans = max(ans, make_tuple(h + l + 1, SA.sa[q] - h - 1, SA.sa[p] - h - 1));
  156.         }
  157.  
  158.         for (int p: stA[y]) stA[x].insert(p);
  159.         for (int p: stB[y]) stB[x].insert(p);
  160.         stA[y].clear();
  161.         stB[y].clear();
  162.  
  163.         pa[y] = x;
  164.         sz[x] += sz[y];
  165.     };
  166.  
  167.     for (int i = 0; i < maxn; i++) pa[i] = i, sz[i] = 1;
  168.     for (int x: ord) {
  169.         int h = rSA.hei[x];
  170.         join(x-1, x, h);
  171.     }
  172.  
  173.     auto [len, p, q] = ans;
  174.     cout << T.substr(p, len) << '\n' << T.substr(q, len) << '\n';
  175. }
Advertisement
Add Comment
Please, Sign In to add comment