Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- vi buildSuffArray(vi &s)
- {
- int n = s.size();
- vi p(n), cnt(256), c(n);
- for (int i = 0; i < n; ++i)
- ++cnt[s[i]];
- for (int i = 1; i < 256; ++i)
- cnt[i] += cnt[i - 1];
- for (int i = n - 1; i >= 0; --i)
- p[--cnt[s[i]]] = i;
- int ccnt = 1;
- c[p[0]] = 0;
- for (int i = 1; i < n; ++i)
- {
- if (s[p[i]] != s[p[i - 1]])
- ++ccnt;
- c[p[i]] = ccnt - 1;
- }
- for (int h = 0; (1 << h) < n; ++h)
- {
- vi pn(n), cn(n);
- cnt.assign(ccnt, 0);
- for (int i = 0; i < n; ++i)
- {
- pn[i] = p[i] - (1 << h);
- if (pn[i] < 0)
- pn[i] += n;
- }
- for (int i = 0; i < n; ++i)
- cnt[c[pn[i]]]++;
- for (int i = 1; i < ccnt; ++i)
- cnt[i] += cnt[i - 1];
- for (int i = n - 1; i >= 0; --i)
- p[--cnt[c[pn[i]]]] = pn[i];
- cn[p[0]] = 0;
- ccnt = 1;
- for (int i = 1; i < n; ++i)
- {
- int mid1 = (p[i] + (1 << h)) % n;
- int mid2 = (p[i - 1] + (1 << h)) % n;
- if (c[p[i]] != c[p[i - 1]] || c[mid1] != c[mid2])
- ++ccnt;
- cn[p[i]] = ccnt - 1;
- }
- if (ccnt == n)
- return p;
- swap(c, cn);
- }
- return p;
- }
- vi buildLCP(vi &sa, vi &s)
- {
- int n = s.size();
- vi lcp(n);
- vi pos(n);
- int l = 0;
- for (int i = 0; i < n; ++i)
- {
- pos[sa[i]] = i;
- }
- for (int i = 0; i < n; ++i)
- {
- if (pos[i] == n - 1)
- {
- l = 0;
- continue;
- }
- l = max(l - 1, 0);
- int j = sa[pos[i] + 1];
- while (l < n && s[(i + l) % n] == s[(j + l) % n])
- ++l;
- lcp[pos[i]] = l;
- }
- return lcp;
- }
- int solve(int n)
- {
- vi a(n);
- for (int i = 0; i < n; ++i)
- {
- scanf("%d", &a[i]);
- }
- vi sa = buildSuffArray(a);
- vi lcp = buildLCP(sa, a);
- ll ans = 0;
- for (int i = 0; i < n - 1; ++i)
- {
- ans += (ll)lcp[i];
- }
- printf("%lld\n", ans);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement