Advertisement
K_Y_M_bl_C

Untitled

Sep 22nd, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.77 KB | None | 0 0
  1. //#define _GLIBCXX_DEBUG
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <bits/stdc++.h>
  4.  
  5. #define FAST_ALLOCATOR_MEMORY 2e8
  6.  
  7. #ifdef FAST_ALLOCATOR_MEMORY
  8.     int allocator_pos = 0;
  9.     char allocator_memory[(int)FAST_ALLOCATOR_MEMORY];
  10.     inline void * operator new ( size_t n ) {
  11.         char *res = allocator_memory + allocator_pos;
  12.         allocator_pos += n;
  13.         assert(allocator_pos <= (int)FAST_ALLOCATOR_MEMORY);
  14.         return (void *)res;
  15.     }
  16.     inline void operator delete ( void * ) noexcept { }
  17.     //inline void * operator new [] ( size_t ) { assert(0); }
  18.     //inline void operator delete [] ( void * ) { assert(0); }
  19. #endif
  20.  
  21. using namespace std;
  22.  
  23. typedef long long ll;
  24. typedef pair<int, int> pii;
  25. typedef vector<int> vi;
  26. typedef long double ld;
  27.  
  28. #define mk make_pair
  29. #define inb push_back
  30. #define X first
  31. #define Y second
  32. #define all(v) v.begin(), v.end()
  33. #define sqr(x) (x) * (x)
  34. #define TIME 1.0 * clock() / CLOCKS_PER_SEC
  35. #define y1 AYDARBOG
  36. //continue break pop_back return
  37.  
  38. int solve();
  39.  
  40. int main()
  41. {
  42.     //ios_base::sync_with_stdio(0);
  43.     //cin.tie(0);
  44. #define TASK "lzss"
  45. #ifndef _DEBUG
  46.     //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
  47. #endif
  48.     solve();
  49. #ifdef _DEBUG
  50.     fprintf(stderr, "\nTIME: %.3f\n", TIME);
  51. #endif
  52. }
  53.  
  54. const int STRSZ = (int)2e5 + 7;
  55. //read str
  56. char buf[STRSZ];
  57. string get_str()
  58. {
  59.     scanf(" %s", buf);
  60.     return string(buf);
  61. }
  62.  
  63. vi buildSuffArray (string &s, int n)
  64. {
  65.     int sz = 256;
  66.     vi p(n), c(n), cnt(sz);
  67.     for (int i = 0; i < n; ++i)
  68.         ++cnt[s[i]];
  69.     for (int i = 1; i < sz; ++i)
  70.         cnt[i] += cnt[i - 1];
  71.     for (int i = n - 1; i >= 0; --i)
  72.         p[--cnt[s[i]]] = i;
  73.     sz = 1;
  74.     c[p[0]] = 0;
  75.     for (int i = 1; i < n; ++i)
  76.     {
  77.         if (s[p[i]] != s[p[i - 1]])
  78.             ++sz;
  79.         c[p[i]] = sz - 1;
  80.     }
  81.     vi pn(n), cn(n);
  82.     for (int h = 0; (1 << h) < n; ++h)
  83.     {
  84.         cnt.assign(sz, 0);
  85.         for (int i = 0; i < n; ++i)
  86.             pn[i] = (p[i] - (1 << h) >= 0) ? (p[i] - (1 << h)) : (p[i] - (1 << h) + n);
  87.         for (int i = 0; i < n; ++i)
  88.             ++cnt[c[pn[i]]];
  89.         for (int i = 1; i < sz; ++i)
  90.             cnt[i] += cnt[i - 1];
  91.         for (int i = n - 1; i >= 0; --i)
  92.             p[--cnt[c[pn[i]]]] = pn[i];
  93.         sz = 1;
  94.         cn[p[0]] = 0;
  95.         for (int i = 1; i < n; ++i)
  96.         {
  97.             int m1 = (p[i] + (1 << h)) % n;
  98.             int m2 = (p[i - 1] + (1 << h)) % n;
  99.             if (c[p[i]] != c[p[i - 1]] || c[m1] != c[m2])
  100.                 ++sz;
  101.             cn[p[i]] = sz - 1;
  102.         }
  103.         if (sz == n)
  104.         {
  105.             return p;
  106.         }
  107.         swap(c, cn);
  108.     }
  109.     return p;
  110. }
  111.  
  112. vi buildLCP (string &s, int n, vi& sa)
  113. {
  114.     vi lcp(n);
  115.     int l = 0;
  116.     vi pos(n);
  117.     for (int i = 0; i < n; ++i)
  118.     {
  119.         pos[sa[i]] = i;
  120.     }
  121.     for (int i = 0; i < n; ++i)
  122.     {
  123.         if (pos[i] == n - 1)
  124.         {
  125.             l = 0;
  126.             continue;
  127.         }
  128.         l = max(l - 1, 0);
  129.         int j = sa[pos[i] + 1];
  130.         while (max(i, j) + l < n && s[i + l] == s[j + l] && s[i + l] != '$')
  131.             ++l;
  132.         lcp[pos[i]] = l;
  133.     }
  134.     return lcp;
  135. }
  136.  
  137. struct SegmentTree
  138. {
  139.     int n;
  140.     vi t;
  141.     SegmentTree() {};
  142.     SegmentTree(vi &a)
  143.     {
  144.         n = a.size();
  145.         t.resize(4 * n);
  146.         build(0, 0, n - 1, a);
  147.     }
  148.     void build(int v, int tl, int tr, vi& a)
  149.     {
  150.         if (tl == tr)
  151.         {
  152.             t[v] = a[tl];
  153.             return;
  154.         }
  155.         int tm = tl + tr >> 1;
  156.         build(2 * v + 1, tl, tm, a);
  157.         build(2 * v + 2, tm + 1, tr, a);
  158.         t[v] = min(t[2 * v + 1], t[2 * v + 2]);
  159.     }
  160.     int slide_left(int v, int tl, int tr, int l, int r, int val)
  161.     {
  162.         if (tl > r || tr < l || t[v] >= val)
  163.             return -1;
  164.         if (tl == tr)
  165.             return tl;
  166.         int tm = tl + tr >> 1;
  167.         int rans = slide_left(2 * v + 2, tm + 1, tr, l, r, val);
  168.         return (rans == -1) ? slide_left(2 * v + 1, tl, tm, l, r, val) : rans;
  169.     }
  170.     int slide_right(int v, int tl, int tr, int l, int r, int val)
  171.     {
  172.         if (tl > r || tr < l || t[v] >= val)
  173.             return -1;
  174.         if (tl == tr)
  175.             return tl;
  176.         int tm = tl + tr >> 1;
  177.         int lans = slide_right(2 * v + 1, tl, tm, l, r, val);
  178.         return (lans == -1) ? slide_right(2 * v + 2, tm + 1, tr, l, r, val) : lans;
  179.     }
  180. };
  181.  
  182. struct Node
  183. {
  184.     int x;
  185.     Node *l, *r;
  186.     Node() { x = 0, l = NULL, r = NULL; };
  187.     Node(int x) : x(x), l(NULL), r(NULL) {};
  188.     Node(int x, Node *l, Node *r) : x(x), l(l), r(r) {};
  189. };
  190.  
  191. int get_x(Node *t)
  192. {
  193.     if (!t)
  194.         return 0;
  195.     return t->x;
  196. }
  197.  
  198. struct PersistentSegmentTree
  199. {
  200.     int n;
  201.     vector<Node*> tv;
  202.     PersistentSegmentTree() {};
  203.     PersistentSegmentTree(int _n)
  204.     {
  205.         n = _n;
  206.         Node *r = new Node();
  207.         tv.inb(r);
  208.         tv.back() = build(tv.back(), 1, n);
  209.     }
  210.     Node *build(Node *t, int tl, int tr)
  211.     {
  212.         if (tl == tr)
  213.         {
  214.             return new Node();
  215.         }
  216.         t->l = new Node();
  217.         t->r = new Node();
  218.         int tm = tl + tr >> 1;
  219.         return new Node(0, build(t->l, tl, tm), build(t->r, tm + 1, tr));
  220.     }
  221.     void upd(int pos)
  222.     {
  223.         Node *r = new Node();
  224.         r = update(tv.back(), 1, n, pos);
  225.         tv.inb(r);
  226.     }
  227.     Node *update(Node *t, int tl, int tr, int pos)
  228.     {
  229.         if (tl == tr)
  230.         {
  231.             return new Node(t->x + 1, 0, 0);
  232.         }
  233.         int tm = tl + tr >> 1;
  234.         if (tl <= pos && pos <= tm)
  235.         {
  236.             Node *nn = update(t->l, tl, tm, pos);
  237.             return new Node(get_x(nn) + get_x(t->r), nn, t->r);
  238.         }
  239.         else
  240.         {
  241.             Node *nn = update(t->r, tm + 1, tr, pos);
  242.             return new Node(get_x(t->l) + get_x(nn), t->l, nn);
  243.         }
  244.     }
  245.     int get_res(int l, int r)
  246.     {
  247.         return get(tv[r + 1], 1, n, r + 1, n) - get(tv[l], 1, n, r + 1, n);
  248.     }
  249.     int get(Node *t, int tl, int tr, int l, int r)
  250.     {
  251.         if (tr < l || tl > r)
  252.             return 0;
  253.         if (l <= tl && tr <= r)
  254.             return t->x;
  255.         int tm = tl + tr >> 1;
  256.         return get(t->l, tl, tm, l, r) + get(t->r, tm + 1, tr, l, r);
  257.     }
  258. };
  259.  
  260. vi calcnxt(vi &c, vi &a)
  261. {
  262.     int n = a.size();
  263.     vi q(n);
  264.     for (int i = 0; i < n; ++i)
  265.     {
  266.         q[i] = c[a[i]];
  267.     }
  268.     vi lst(n + 2, -1);
  269.     vi nxt(n, n);
  270.     for (int i = 0; i < n; ++i)
  271.     {
  272.         if (lst[q[i]] != -1)
  273.         {
  274.             nxt[lst[q[i]]] = i;
  275.         }
  276.         lst[q[i]] = i;
  277.     }
  278.     return nxt;
  279. }
  280.  
  281. int solve()
  282. {
  283.     string s, cur;
  284.     int k;
  285.     scanf("%d", &k);
  286.     for (int i = 0; i < k; ++i)
  287.     {
  288.         cur = get_str();
  289.         s += cur;
  290.         s.inb('$');
  291.     }
  292.     int n = s.size();
  293.     vi col(n);
  294.     int dolc = 0;
  295.     for (int i = 0; i < n; ++i)
  296.     {
  297.         col[i] = dolc;
  298.         if (s[i] == '$')
  299.         {
  300.             ++dolc;
  301.         }
  302.     }
  303.     vi sa = buildSuffArray(s, n);
  304.     vi lcp = buildLCP(s, n, sa);
  305.     vi ans(k + 1);
  306.     vi nxt = calcnxt(col, sa);
  307.     SegmentTree Tlcp = SegmentTree(lcp);
  308.     PersistentSegmentTree Tnxt = PersistentSegmentTree(n);
  309.     for (int i = 0; i < n; ++i)
  310.     {
  311.         Tnxt.upd(nxt[i]);
  312.     }
  313.     for (int i = 0; i < n; ++i)
  314.     {
  315.         if (!lcp[i])
  316.             continue;
  317.         int l = Tlcp.slide_left(0, 0, n - 1, 0, i, lcp[i]) + 1;
  318.         int r = Tlcp.slide_right(0, 0, n - 1, i, n - 1, lcp[i]);
  319.         int cnt = Tnxt.get_res(l, r);
  320.         ans[cnt] = max(ans[cnt], lcp[i]);
  321.     }
  322.     for (int i = k - 1; i >= 2; --i)
  323.         ans[i] = max(ans[i + 1], ans[i]);
  324.     for (int i = 2; i <= k; ++i)
  325.         printf("%d\n", ans[i]);
  326.     return 0;
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement