string tmp = s + "&" + rs; SA sa(tmp); SparseTable<int> qmx(sa.lc, [](int i, int j) { return min(i, j); });
auto pre = [&](PAM& pp, string tt) { deb(tt); pp.work(tt); int tot = pp.t.size() - 1; vector<vector<int>> e(tot + 1); for (int i = 2; i <= tot; i++) e[pp.fail(i)].push_back(i); int jie = __lg(tot); vector st(jie + 1, vector<int>(tot + 1));
auto dfs = [&](auto self, int u) -> void { for (auto v : e[u]) { // deb(u, v); st[0][v] = u; self(self, v); } };
dfs(dfs, 1); for (int j = 1; j <= jie; j++) { for (int i = 1; i <= tot; i++) { st[j][i] = st[j - 1][st[j - 1][i]]; } } return st; }; auto getlcp = [&](int pos1, int pos2) { int c1 = min(sa.rk[pos1], sa.rk[pos2]); int c2 = max(sa.rk[pos1], sa.rk[pos2]); assert(c1 < c2); return qmx.get(c1 + 1, c2); }; auto st1 = pre(pam1, s); auto st2 = pre(pam2, rs); int tot1 = pam1.size() - 1, tot2 = pam2.size() - 1; int jie1 = __lg(tot1), jie2 = __lg(tot2); deb(s);
int m; cin >> m; auto id = [&](int x) { return2 * n + 2 - x; }; for (int i = 1; i <= m; i++) { int l, r; cin >> l >> r; int lcp1 = getlcp(l, id(r)); int len = r - l + 1; if (len == 1) { cout << 0 << " " << 0 << endl; continue; } lcp1 = min(lcp1, len); deb(lcp1); if (lcp1 == len) { cout << 0 << " " << 0 << endl; continue; }
int ql = l + lcp1, qr = r - lcp1; int cur = pam1.idpos[qr], cul = pam2.idpos[n + 1 - ql]; deb(ql, qr); // deb(cur, cul); deb(pam1.len(cur), pam2.len(cul)); int maxpre, maxsuf; if (pam1.len(cur) <= qr - ql + 1) { maxsuf = pam1.len(cur); } else { for (int j = jie1; j >= 0; j--) { if (pam1.len(st1[j][cur]) > qr - ql + 1) { cur = st1[j][cur]; } } maxsuf = max(pam1.len(st1[0][cur]), 1); } //-------------------- if (pam2.len(cul) <= qr - ql + 1) { maxpre = pam2.len(cul); } else { for (int j = jie2; j >= 0; j--) { if (pam2.len(st2[j][cul]) > qr - ql + 1) { cul = st2[j][cul]; } }
maxpre = max(1, pam2.len(st2[0][cul])); } // deb(cur, cul); deb(maxpre, maxsuf); int ans1 = qr - ql + 1 - max(maxsuf, maxpre); int ans2 = 0; assert(ans1 < qr - ql + 1); deb("aaa"); if (qr - ql + 1 - maxsuf == ans1) { ans2++; int fl = ql, fr = fl + ans1 - 1; deb("maxsuf", fl, fr); if (id(fl - 1) > n + 1 && id(fl - 1) < 2 * n + 2) { int tmpcp = getlcp(id(fl - 1), id(fr)); tmpcp = min(tmpcp, fl - 1 - l + 1); ans2 += tmpcp; } } deb("aaa"); if (qr - ql + 1 - maxpre == ans1) { ans2++; int fr = qr, fl = fr - ans1 + 1; if ((fr + 1) < n + 1) { int tmpcp = getlcp(fr + 1, fl); tmpcp = min(tmpcp, r - (fr + 1) + 1); ans2 += tmpcp; } } cout << ans1 << " " << ans2 << endl; } }