QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#246930 | #7627. Phony | ucup-team022# | WA | 0ms | 24432kb | C++17 | 3.0kb | 2023-11-11 12:44:00 | 2023-11-11 12:44:01 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 LL;
const LL B = 23333, mod = 999999999999989ll;
int n, m;
LL hsh1[800005], hsh2[800005], pw[800005];
char a[800005];
struct PAM {
int fail[800005], c[800005][30], len[800005], tot, _n;
int tmp[800005], pos[800005], lst, _p[800005][30];
// 0奇根 1偶根
void init() { len[0] = -1, len[1] = fail[1] = 0, tot = 1, lst = 0; }
void Ins(int x) {
// cout<<"Insert:"<<x<<'\n';
tmp[++tmp[0]] = x;
int p = lst;
while (p && (tmp[0] - 1 - len[p] <= 0 || tmp[tmp[0] - 1 - len[p]] != x)) p = fail[p];
if (c[p][x] > 1) return lst = c[p][x], void();
lst = c[p][x] = ++tot, len[tot] = len[p] + 2, p = fail[p];
while (p && tmp[tmp[0] - 1 - len[p]] != x) p = fail[p];
if (c[p][x] != tot) fail[tot] = c[p][x];
else fail[tot] = 1;
_p[tot][0] = fail[tot];
for (int i = 1; i <= 18; i++) _p[tot][i] = _p[_p[tot][i - 1]][i - 1];
}
void Build(char *s, int n) {
_n = n;
for (int i = 1; i <= n; i++) Ins(s[i] - 'a'), pos[i] = lst;
}
bool Check(int l, int r) {
if (r > n || l < 0) return 0;
int x = pos[r];
for (int j = 18; j >= 0; j--) {
if (len[_p[x][j]] >= r - l + 1) x = _p[x][j];
}
return len[x] == r - l + 1;
}
int getM(int l, int r) {
int x = pos[r];
for (int j = 18; j >= 0; j--) {
if (len[_p[x][j]] > r - l + 1) x = _p[x][j];
}
if (len[x] > r - l + 1) x = fail[x];
return len[x];
}
} lr, rl;
LL getH(LL h[], int l, int r) { return (h[r] - h[l - 1] * pw[r - l + 1] % mod + mod) % mod; }
int Getmx(int l, int r) {
int s = 0;
for (int i = 18; i >= 0; i--) {
int ss = s + (1 << i);
if (ss >= l || ss >= n + 1 - r) continue;
if (getH(hsh1, l - ss, r + ss) == getH(hsh2, n + 1 - r - ss, n + 1 - l + ss)) {
s = ss;
}
}
return s;
}
int main() {
lr.init(), rl.init();
scanf("%d%s%d", &n, a + 1, &m);
for (int i = 1; i <= n; i++) hsh1[i] = (hsh1[i - 1] * B + a[i]) % mod;
lr.Build(a, n);
reverse(a + 1, a + n + 1), rl.Build(a, n);
for (int i = 1; i <= n; i++) hsh2[i] = (hsh2[i - 1] * B + a[i]) % mod;
pw[0] = 1;
for (int i = 1; i <= n; i++) pw[i] = pw[i - 1] * B % mod;
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
if (lr.Check(l, r)) {
puts("0 0");
continue;
}
int mx = (r - l + 1) / 2, s = 0;
for (int i = 18; i >= 0; i--) {
int ss = s + (1 << i);
if (ss > mx) continue;
if (getH(hsh1, l, l + ss - 1) == getH(hsh2, n - r + 1, n - r + ss)) {
s = ss;
}
}
int lll = l + s, rr = r - s;
int v1 = lr.getM(lll, rr), v2 = rl.getM(n - rr + 1, n - lll + 1);
// cout << lll << ' ' << rr << ' ' << v1 << ' ' << v2 << '\n';
// cout << rr - lll + 1 - max(v1, v2) << ' ' << 1 + (v1 == v2) << '\n';
int u1 = Getmx(rr - v1 + 1, rr);
int u2 = Getmx(lll, lll + v2 - 1);
if (v1 > v2) {
cout << rr - lll + 1 - v1 << ' ' << u1 + 1 << '\n';
} else if (v2 > v1) {
cout << rr - lll + 1 - v2 << ' ' << u2 + 1 << '\n';
} else {
cout << rr - lll + 1 - v2 << ' ' << u1 + u2 + 2 << '\n';
}
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 24432kb
input:
3 5 5 7 3 9 A 3 C 1 A 2 C 2 A 3
output:
-2 2 -4 2 -4 2 -4 2 -4 2
result:
wrong answer 1st lines differ - expected: '3', found: '-2 2'