volochai

CF129 E

Jun 11th, 2024
427
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.37 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define ll long long
  4. #define all(x) (x).begin(), (x).end()
  5. #define rall(x) (x).rbegin(), (x).rend()
  6. #define watch(x) cout << (#x) << " : " << x << '\n'
  7. #define boost ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  8.  
  9. using namespace std;
  10.  
  11. vector <int> build(vector<int> s) {
  12.     int n = (int)s.size();
  13.     const int A = max(256, n + 1);
  14.     vector <int> cnt(A), p(n), c(n);
  15.     for (int i = 0; i < n; i++)
  16.         cnt[s[i]]++;
  17.     for (int i = 1; i < A; i++)
  18.         cnt[i] += cnt[i - 1];
  19.     for (int i = 0; i < n; i++)
  20.         p[--cnt[s[i]]] = i;
  21.  
  22.     c[p[0]] = 0;
  23.     for (int i = 1; i < n; i++)
  24.         c[p[i]] = c[p[i - 1]] + (s[p[i]] != s[p[i - 1]]);
  25.  
  26.     vector <int> nxt(n), l(n);
  27.     for (int k = 0; (1 << k) < n; k++) {
  28.         for (int i = 0; i < n; i++)
  29.             l[i] = (p[i] - (1 << k) + n) % n;
  30.         fill(cnt.begin(), cnt.begin() + c[p.back()] + 1, 0);
  31.         for (int i = 0; i < n; i++)
  32.             cnt[c[l[i]]]++;
  33.         for (int i = 1; i <= c[p.back()]; i++)
  34.             cnt[i] += cnt[i - 1];
  35.         for (int i = n - 1; i >= 0; i--)
  36.             p[--cnt[c[l[i]]]] = l[i];
  37.  
  38.         nxt[p[0]] = 0;
  39.         for (int i = 1; i < n; i++)
  40.             nxt[p[i]] = nxt[p[i - 1]] +
  41.                         (make_pair(c[p[i]], c[(p[i] + (1 << k)) % n]) != make_pair(c[p[i - 1]], c[(p[i - 1] + (1 << k)) % n]));
  42.         c.swap(nxt);
  43.     }
  44.     return p;
  45. }
  46.  
  47. int n, k;
  48.  
  49. const int N = 2e5 + 128;
  50. const int LOG = 19;
  51. int dp[N][LOG], lg2[N];
  52.  
  53. int get(int l, int r) {
  54.     int k = lg2[r-l+1];
  55.     return min(dp[l][k], dp[r-(1<<k)+1][k]);
  56. }
  57.  
  58. void solve() {
  59.     cin >> n >> k;
  60.     vector <int> total, after;
  61.     set <int> bad;
  62.     for (int i = 0; i < n; i++) {
  63.         string s;
  64.         cin >> s;
  65.         after.push_back((int)total.size());
  66.         for (int c = 0; c < (int)s.size(); c++)
  67.             total.push_back(int(s[c]) + n + 1);
  68.         bad.insert((int)total.size());
  69.         total.push_back(n-i);
  70.     }
  71.  
  72.     vector <int> to_compress = total;
  73.     sort(all(to_compress));
  74.     to_compress.resize(unique(all(to_compress)) - to_compress.begin());
  75.     map <int, int> val;
  76.     for (int i = 0; i < (int)to_compress.size(); i++)
  77.         val[to_compress[i]] = i;
  78.     for (int i = 0; i < (int)total.size(); i++)
  79.         total[i] = val[total[i]];
  80.  
  81.     vector <int> p = build(total);
  82.  
  83.     int sz = (int)p.size();
  84.     vector <int> pos(sz);
  85.     for (int i = 0; i < sz; i++)
  86.         pos[p[i]] = i;
  87.  
  88.     vector <int> lcp(sz, 0);
  89.     int len = 0;
  90.  
  91.     for (int i = 0; i + 1 < sz; i++) {
  92.         len = max(len - 1, 0);
  93.  
  94.         int c = pos[i];
  95.         int j = p[c - 1];
  96.  
  97.         while (total[i + len] == total[j + len])
  98.             ++len;
  99.  
  100.         lcp[c - 1] = len;
  101.     }
  102.  
  103.     int m = sz - 1;
  104.     for (int i = 0; i < m; i++)
  105.         dp[i][0] = lcp[i];
  106.     for (int b = 1; b < LOG; b++)
  107.         for (int i = 0; i < m; i++)
  108.             if (i + (1 << b) - 1 < m)
  109.                 dp[i][b] = min(dp[i][b - 1], dp[i + (1 << (b - 1))][b - 1]);
  110.  
  111.     vector <int> host(sz);
  112.     for (int i = 0; i < sz; i++)
  113.         if (bad.count(p[i]))
  114.             host[i] = -1;
  115.         else
  116.             host[i] = (int)(upper_bound(all(after), p[i]) - after.begin());
  117.  
  118.     vector <int> R(sz, 1e9);
  119.     set <int> st;
  120.     map <int, int> cnt;
  121.  
  122.     auto add = [&](int x) -> void {
  123.         if (cnt[x] == 0)
  124.             st.insert(x);
  125.         cnt[x]++;
  126.     };
  127.  
  128.     auto del = [&](int x) -> void {
  129.         cnt[x]--;
  130.         if (cnt[x] == 0)
  131.             st.erase(x);
  132.     };
  133.  
  134.     auto get_size = [&]() -> int {
  135.         return (int)st.size() - st.count(-1);
  136.     };
  137.  
  138.     int to = -1;
  139.     for (int i = 0; i < sz; i++) {
  140.         while (to + 1 < sz && get_size() < k)
  141.             add(host[++to]);
  142.  
  143.         if (get_size() >= k)
  144.             R[i] = to;
  145.         del(host[i]);
  146.     }
  147.  
  148.     vector <ll> res(n + 1);
  149.  
  150.     for (int i = 0; i < sz; i++) {
  151.         if (host[i] == -1)
  152.             continue;
  153.         auto check = [&](int x) -> bool {
  154.             int l = i;
  155.             if (i && lcp[i - 1] >= x) {
  156.                 int lx = 0, rx = i - 1;
  157.                 while (lx + 1 < rx) {
  158.                     int mx = (lx + rx) >> 1;
  159.                     if (get(mx, i - 1) >= x)
  160.                         rx = mx;
  161.                     else
  162.                         lx = mx;
  163.                 }
  164.                 if (get(lx, i - 1) >= x) l = lx;
  165.                 else l = rx;
  166.             }
  167.  
  168.             int r = i;
  169.             if (lcp[i] >= x) {
  170.                 int lx = i, rx = sz - 1;
  171.                 while (lx + 1 < rx) {
  172.                     int mx = (lx + rx) >> 1;
  173.                     if (get(i, mx) < x)
  174.                         rx = mx;
  175.                     else
  176.                         lx = mx;
  177.                 }
  178.                 if (get(i, rx) < x) r = rx;
  179.                 else r = lx;
  180.             }
  181.  
  182.             return R[l] <= r;
  183.         };
  184.         int nxt_bad = *bad.lower_bound(p[i])-p[i];
  185.         int l = 0, r = nxt_bad + 1;
  186.         while (l + 1 < r) {
  187.             int m = (l + r) >> 1;
  188.             if (check(m))
  189.                 l = m;
  190.             else
  191.                 r = m;
  192.         }
  193.         res[host[i]] += l;
  194.     }
  195.  
  196.     for (int i = 1; i <= n; i++)
  197.         cout << res[i] << ' ';
  198.     cout << '\n';
  199.  
  200. }
  201.  
  202. main() {
  203.     boost;
  204.  
  205.     for (int i = 2; i < N; i++)
  206.         lg2[i] = lg2[i / 2] + 1;
  207.  
  208.     solve();
  209.     return 0;
  210. }
Advertisement
Add Comment
Please, Sign In to add comment