cosenza987

Untitled

Jun 7th, 2024
585
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.41 KB | None | 0 0
  1. //Слава Україні, Героям слава
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. struct SuffixArray {
  8.     vector<int> sa, lcp_v;
  9.     vector<vector<int>> cs;
  10.     int n;
  11.  
  12.     int add(int a, int b) { return a + b >= n ? a + b - n : a + b; }
  13.     int sub(int a, int b) { return a - b < 0 ? a - b + n : a - b; }
  14.  
  15.     SuffixArray(string& s, bool store_steps = false, bool build_lcp = true) {
  16.         s += ' ';
  17.         n = (int)s.size();
  18.         sa = sort_shifts(s, store_steps);
  19.         if (build_lcp) {
  20.             lcp_v = build_lcp_v(s);
  21.             lcp_v.erase(lcp_v.begin());
  22.         }
  23.         sa.erase(sa.begin());
  24.         s.pop_back();
  25.     }
  26.  
  27.     vector<int> sort_shifts(string& s, bool store_steps) {
  28.         const int ALPHA_SIZE = 256;
  29.         vector<int> p(n), c(n), cnt(ALPHA_SIZE);
  30.         for (char ch : s) cnt[(int)ch]++;
  31.         for (int i = 1; i < ALPHA_SIZE; i++) cnt[i] += cnt[i - 1];
  32.  
  33.         for (int i = 0; i < n; i++) {
  34.             cnt[s[i]]--;
  35.             p[cnt[s[i]]] = i;
  36.         }
  37.  
  38.         for (int i = 1; i < n; i++)
  39.             c[p[i]] = c[p[i - 1]] + (s[p[i]] != s[p[i - 1]]);
  40.  
  41.         if (store_steps) cs.push_back(c);
  42.  
  43.         vector<int> cn(n), pn(n);
  44.  
  45.         for (int k = 0; (1 << k) < n; k++) {
  46.             int nclass = c[p[n - 1]] + 1;
  47.             cnt.assign(nclass, 0);
  48.  
  49.             for (int i = 0; i < n; i++) {
  50.                 pn[i] = sub(p[i], (1 << k));
  51.                 cnt[c[i]]++;
  52.             }
  53.  
  54.             for (int i = 1; i < nclass; i++)
  55.                 cnt[i] += cnt[i - 1];
  56.  
  57.             for (int i = n - 1; i >= 0; i--) {
  58.                 cnt[c[pn[i]]]--;
  59.                 p[cnt[c[pn[i]]]] = pn[i];
  60.             }
  61.  
  62.             cn[p[0]] = 0;
  63.             for (int i = 1; i < n; i++) {
  64.                 pair<int, int> a = { c[p[i]], c[add(p[i], (1 << k))] };
  65.                 pair<int, int> b = { c[p[i - 1]], c[add(p[i - 1], (1 << k))] };
  66.                 cn[p[i]] = cn[p[i - 1]] + (a != b);
  67.             }
  68.  
  69.             swap(c, cn);
  70.             if (store_steps) cs.push_back(c);
  71.  
  72.         }
  73.  
  74.         return p;
  75.     }
  76.  
  77.     vector<int> build_lcp_v(string& s) {
  78.         vector<int> ans(n - 1), rank(n);
  79.         for (int i = 0; i < n; i++) rank[sa[i]] = i;
  80.  
  81.         for (int i = 0, k = 0; i < n - 1; i++) {
  82.             if (rank[i] == n - 1) continue;
  83.             int j = sa[rank[i] + 1];
  84.             while (s[i + k] == s[j + k]) k++;
  85.             ans[rank[i]] = k;
  86.             if (k) k--;
  87.         }
  88.  
  89.         return ans;
  90.     }
  91.  
  92.     int lcp(int i, int j) {
  93.         if (i == j) return n - i - 1;
  94.         int ans = 0;
  95.         for (int k = (int)cs.size() - 1; k >= 0; k--) {
  96.             if (cs[k][i] == cs[k][j]) {
  97.                 int val = (1 << k);
  98.                 ans += val, i += val, j += val;
  99.             }
  100.         }
  101.         return ans;
  102.     }
  103.  
  104.     long long diff_substr() {
  105.         int sz = n - 1;
  106.         long long ans = sz - sa[0];
  107.         for (int i = 1; i < (int)sa.size(); i++) ans += sz - sa[i] - lcp_v[i - 1];
  108.         return ans;
  109.     }
  110.  
  111.     long long diff_substr_sz_sum() {
  112.         int sz = n - 1;
  113.         auto sum = [](int l, int r) { return (1ll * (l + r) * (r - l + 1)) / 2; };
  114.         long long ans = sum(1, sz - sa[0]);
  115.         for (int i = 1; i < (int)sa.size(); i++) ans += sum(lcp_v[i - 1] + 1, sz - sa[i]);
  116.         return ans;
  117.     }
  118.  
  119. };
  120.  
  121. const int N = 1e6 + 7;
  122.  
  123. int par[N], sz[N];
  124.  
  125. int find(int a) {
  126.     return a == par[a] ? a : par[a] = find(par[a]);
  127. }
  128.  
  129. void unite(int a, int b) {
  130.     if((a = find(a)) == (b = find(b))) return;
  131.     if(sz[b] > sz[a]) swap(a, b);
  132.     sz[a] += sz[b];
  133.     par[b] = a;
  134. }
  135.  
  136. int main() {
  137.     ios_base::sync_with_stdio(false);
  138.     cin.tie(nullptr);
  139.     for(int i = 0; i < N; i++) {
  140.         par[i] = i;
  141.         sz[i] = 1;
  142.     }
  143.     long long n, k;
  144.     cin >> n >> k;
  145.     string s;
  146.     cin >> s;
  147.     SuffixArray sa(s);
  148.     vector<vector<pair<int, int>>> q(n + 1);
  149.     vector<int> invsa(n);
  150.     for(int i = 0; i < (int)sa.lcp_v.size(); i++) {
  151.         q[sa.lcp_v[i]].emplace_back(sa.sa[i], sa.sa[i + 1]);
  152.     }
  153.     for(int i = 0; i < n; i++) {
  154.         invsa[sa.sa[i]] = i;
  155.     }
  156.     vector<pair<int, int>> ans;
  157.     for(long long i = n; i; i--) {
  158.         for(auto [a, b] : q[i]) {
  159.             unite(a, b);
  160.         }
  161.         for(auto [a, b] : q[i]) {
  162.             if(i * sz[find(a)] == k) {
  163.                 ans.emplace_back(find(a), i);
  164.             }
  165.         }
  166.     }
  167.     // i forgot to add the ones of length k that have nothing in common lol
  168.     for(int i = 1; i < n - 1; i++) {
  169.         if(sa.lcp_v[i - 1] < k and sa.lcp_v[i] < k) {
  170.             if(n - sa.sa[i] >= k) {
  171.                 ans.emplace_back(sa.sa[i], k);
  172.             }
  173.         }
  174.     }
  175.     if(sa.lcp_v[0] < k and n - sa.sa[0] >= k) {
  176.         ans.emplace_back(sa.sa[0], k);
  177.     }
  178.     if(sa.lcp_v[n - 2] < k and n - sa.sa[n - 1] >= k) {
  179.         ans.emplace_back(sa.sa[n - 1], k);
  180.     }
  181.     sort(ans.begin(), ans.end(), [&](pair<int, int> a, pair<int, int> b) {
  182.         if(invsa[a.first] == invsa[b.first]) {
  183.             return a.second < b.second;
  184.         }
  185.         return invsa[a.first] < invsa[b.first];
  186.     });
  187.     ans.erase(unique(ans.begin(), ans.end()), ans.end());
  188.     cout << ans.size() << "\n";
  189.     if(ans.size()) {
  190.         cout << s.substr(ans[0].first, ans[0].second) << "\n";
  191.         cout << s.substr(ans.back().first, ans.back().second) << "\n";
  192.     }
  193.     return 0;
  194. }
Advertisement
Add Comment
Please, Sign In to add comment