Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- const int maxN = 1e6 + 10;
- const int inf = 1e9;
- int cur_len, str_len;
- int cnt = 1, cur, pos;
- int to[maxN][26], len[maxN], first_pos[maxN], link[maxN];
- int dist[maxN], max_len[maxN][2];
- bool leaf[maxN];
- std::string str;
- int make (int _pos, int _len) {
- len[cnt] = _len;
- first_pos[cnt] = _pos;
- return cnt++;
- }
- void add (int sym) {
- cur_len++;
- pos++;
- int last = 0;
- while (pos) {
- while (pos > len[to[cur][str[cur_len - pos] - 'a']]) {
- cur = to[cur][str[cur_len - pos] - 'a'];
- pos -= len[cur];
- }
- int& vtx = to[cur][str[cur_len - pos] - 'a'];
- if (!vtx) {
- vtx = make(cur_len - pos, inf);
- link[last] = cur;
- last = 0;
- leaf[vtx] = 1;
- } else {
- int tmp = str[first_pos[vtx] + pos - 1] - 'a';
- if (tmp == sym) {
- link[last] = cur;
- return;
- }
- int new_vtx = make(first_pos[vtx], pos - 1);
- to[new_vtx][sym] = make(cur_len - 1, inf);
- leaf[to[new_vtx][sym]] = 1;
- to[new_vtx][tmp] = vtx;
- first_pos[vtx] += pos - 1;
- len[vtx] -= pos - 1;
- vtx = new_vtx;
- link[last] = new_vtx;
- last = new_vtx;
- }
- if (cur) {
- cur = link[cur];
- } else {
- pos--;
- }
- }
- }
- void dfs (int vtx) {
- if (leaf[vtx]) {
- max_len[vtx][0] = dist[vtx];
- }
- for (int i = 0; i < 26; i++) {
- if (to[vtx][i]) {
- int nxt = to[vtx][i];
- dist[nxt] = dist[vtx] + std::min (str_len - first_pos[nxt], len[nxt]);
- dfs(nxt);
- if (max_len[nxt][0] > max_len[vtx][0]) {
- max_len[vtx][1] = std::max (max_len[vtx][0], max_len[nxt][1]);
- max_len[vtx][0] = max_len[nxt][0];
- } else {
- max_len[vtx][1] = std::max (max_len[vtx][1], max_len[nxt][0]);
- }
- }
- }
- }
- int main() {
- len[0] = inf;
- std::cin >> str_len >> str;
- for (auto sym : str) {
- add(sym - 'a');
- }
- int64_t ans = 0;
- dfs(0);
- for (int i = 1; i < cnt; i++) {
- int64_t length = std::min (len[i], str_len - first_pos[i]);
- ans += length * (length - 1) / 2;
- if (!leaf[i]) {
- ans += length * (max_len[i][1] ? max_len[i][0] - max_len[i][1] : 1);
- }
- }
- std::cout << ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement