danielvitor23

Sorting Segments

Jul 21st, 2023 (edited)
1,162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.80 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. using namespace std;
  5.  
  6. using i64 = long long;
  7.  
  8. const int INF = 0x3f3f3f3f;
  9.  
  10. template<class T>
  11. class SegmentTree {
  12.     struct Node {
  13.         T val;
  14.         Node(T x) : val(x) {}
  15.         Node () : val(INF) {}
  16.     };
  17.     int N;
  18.     std::vector<T> a;
  19.     std::vector<Node> tr;
  20.     Node neutral;
  21.     inline Node join(const Node &a, const Node &b) {
  22.         return Node(min(a.val, b.val));
  23.     }
  24.     void build(int node, int l, int r) {
  25.         if (l == r) {
  26.             tr[node] = Node(a[l]);
  27.             return;
  28.         }
  29.         int mid = l+(r-l)/2, lc = (node << 1);
  30.         build(lc, l, mid);
  31.         build(lc+1, mid+1, r);
  32.         tr[node] = join(tr[lc], tr[lc+1]);
  33.     }
  34.     Node query(int node, int l, int r, int ql, int qr) {
  35.         if (r < l or qr < l or r < ql) return neutral;
  36.         if (ql <= l and r <= qr) return tr[node];
  37.         int mid = l+(r-l)/2, lc = (node << 1);
  38.         return join(query(lc, l, mid, ql, qr),
  39.                     query(lc+1, mid+1, r, ql, qr));
  40.     }
  41. public:
  42.     template<class MyIterator>
  43.     SegmentTree (MyIterator begin, MyIterator end) {
  44.         N = end-begin-1;
  45.         tr.assign(4*N, 0);
  46.         a = std::vector<T>(begin, end);
  47.         build(1, 1, N);
  48.     }
  49.     SegmentTree (int n) : N(n) {
  50.         tr.assign(4*N, 0);
  51.         a.assign(N+1, 0);
  52.     }
  53.     T query(int l, int r) {
  54.         return query(1, 1, N, l+1, r+1).val;
  55.     }
  56. };
  57.  
  58. vector<int> sort_cyclic_shifts(const string& s) {
  59.   int n = s.size();
  60.   const int alphabet = 256;
  61.  
  62.     vector<int> p(n), c(n), cnt(max(alphabet, n), 0);
  63.     for (int i = 0; i < n; i++)
  64.         cnt[s[i]]++;
  65.     for (int i = 1; i < alphabet; i++)
  66.         cnt[i] += cnt[i-1];
  67.     for (int i = 0; i < n; i++)
  68.         p[--cnt[s[i]]] = i;
  69.     c[p[0]] = 0;
  70.     int classes = 1;
  71.     for (int i = 1; i < n; i++) {
  72.         if (s[p[i]] != s[p[i-1]])
  73.             classes++;
  74.         c[p[i]] = classes - 1;
  75.     }
  76.  
  77.     vector<int> pn(n), cn(n);
  78.     for (int h = 0; (1 << h) < n; ++h) {
  79.         for (int i = 0; i < n; i++) {
  80.             pn[i] = p[i] - (1 << h);
  81.             if (pn[i] < 0)
  82.                 pn[i] += n;
  83.         }
  84.         fill(cnt.begin(), cnt.begin() + classes, 0);
  85.         for (int i = 0; i < n; i++)
  86.             cnt[c[pn[i]]]++;
  87.         for (int i = 1; i < classes; i++)
  88.             cnt[i] += cnt[i-1];
  89.         for (int i = n-1; i >= 0; i--)
  90.             p[--cnt[c[pn[i]]]] = pn[i];
  91.         cn[p[0]] = 0;
  92.         classes = 1;
  93.         for (int i = 1; i < n; i++) {
  94.             pair<int, int> cur = {c[p[i]], c[(p[i] + (1 << h)) % n]};
  95.             pair<int, int> prev = {c[p[i-1]], c[(p[i-1] + (1 << h)) % n]};
  96.             if (cur != prev)
  97.                 ++classes;
  98.             cn[p[i]] = classes - 1;
  99.         }
  100.         c.swap(cn);
  101.     }
  102.     return p;
  103. }
  104.  
  105. vector<int> suffix_array_construction(string s) {
  106.   s += "$";
  107.   vector<int> sorted_shifts = sort_cyclic_shifts(s);
  108.   sorted_shifts.erase(sorted_shifts.begin());
  109.   return sorted_shifts;
  110. }
  111.  
  112. vector<int> lcp_construction(string const& s, vector<int> const& p) {
  113.   int n = s.size();
  114.   vector<int> rank(n, 0);
  115.   for (int i = 0; i < n; i++)
  116.       rank[p[i]] = i;
  117.  
  118.   int k = 0;
  119.   vector<int> lcp(n-1, 0);
  120.   for (int i = 0; i < n; i++) {
  121.       if (rank[i] == n - 1) {
  122.           k = 0;
  123.           continue;
  124.       }
  125.       int j = p[rank[i] + 1];
  126.       while (i + k < n && j + k < n && s[i+k] == s[j+k])
  127.           k++;
  128.       lcp[rank[i]] = k;
  129.       if (k)
  130.           k--;
  131.   }
  132.   return lcp;
  133. }
  134.  
  135. int n;
  136.  
  137. int main() {
  138.   cin.tie(0)->sync_with_stdio(0);
  139.  
  140.   string s; cin >> s;
  141.  
  142.   n = s.size();
  143.  
  144.   if (n == 1) {
  145.     int m; cin >> m;
  146.     while (m--) {
  147.       int l, r; cin >> l >> r;
  148.       cout << l << ' ' << r << '\n';
  149.     }
  150.  
  151.     return 0;
  152.   }
  153.  
  154.   vector<int> SA = suffix_array_construction(s);
  155.   vector<int> lcp = lcp_construction(s, SA);
  156.  
  157.   lcp.insert(lcp.begin(), 0);
  158.   SegmentTree<int> ST(lcp.begin(), lcp.end());
  159.  
  160.   vector<pair<int, int>> v;
  161.  
  162.   int m; cin >> m;
  163.   while (m--) {
  164.     int l, r; cin >> l >> r, --l, --r;
  165.     v.push_back({l, r});
  166.   }
  167.  
  168.   vector<int> rank(n, 0);
  169.   for (int i = 0; i < n; ++i) {
  170.     rank[SA[i]] = i;
  171.   }
  172.  
  173.   sort(v.begin(), v.end(), [&](pair<int, int> a, pair<int, int> b) {
  174.     int sza = a.se - a.fi + 1, szb = b.se - b.fi + 1;
  175.  
  176.     int k = rank[a.fi] == rank[b.fi]
  177.       ? min(sza, szb)
  178.       : (rank[a.fi] < rank[b.fi]
  179.         ? ST.query(rank[a.fi], rank[b.fi] - 1)
  180.         : ST.query(rank[b.fi], rank[a.fi] - 1));
  181.  
  182.     k = min({ k, sza, szb });
  183.  
  184.     if (k == sza and k == szb)
  185.       return a < b;
  186.     if (k == sza or k == szb)
  187.       return k == sza;
  188.  
  189.     char ca = s[a.fi + k], cb = s[b.fi + k];
  190.  
  191.     return ca < cb;
  192.   });
  193.  
  194.   for (auto [a, b] : v) {
  195.     cout << 1+a << " " << 1+b << '\n';
  196.   }
  197. }
Advertisement
Add Comment
Please, Sign In to add comment