inline modint query(int l, int r){ return h[r] - h[l - 1] * p[r - l + 1]; }
inlineintlcp(int a, int b){ int l = 0, r = min(n - a, n - b) + 1, res = 0; while (l <= r) { int mid = (l + r) >> 1; if (query(a, a + mid - 1) == query(b, b + mid - 1)) l = mid + 1, res = mid; else r = mid - 1; } return res; }
inlinevoidsasort(){ n = strlen(s + 1); p[0] = 1; for (int i = 1; i <= n; i++) { sa[i] = i; h[i] = h[i - 1] * base + modint(s[i]), p[i] = p[i - 1] * base; } stable_sort(sa + 1, sa + n + 1, [](int a, int b) -> bool { int len = lcp(a, b); return s[a + len] < s[b + len]; }); }
inlinevoidsolve_height(){ for (int i = 2; i <= n; i++) ht[i] = lcp(sa[i], sa[i - 1]); } }