题解:P4324 [JSOI2016] 扭动的回文串
现有题解好像都带个
可以注意到如下性质:存在某个最长扭动回文串,其
证明是直观的:任意考虑一个最长扭动回文串,如果它已经满足这一性质,则结束,否则不妨设回文中心在
上述性质说明可以通过扩展极长回文子串的方式得到答案,由此得到一个
为了消掉
核心代码如下:
int solve(const string& a, const string& b) {
int n = a.length();
string aa("#"), raa("#"), rbb("#");
for (int i = 0; i < n; i++) {
aa += a[i];
aa += '#';
raa += a[n - i - 1];
raa += '#';
rbb += b[n - i - 1];
rbb += '#';
}
n = 2 * n + 1;
auto man = manacher(aa);
str_hash hash(aa), hrash(raa), hrbsh(rbb);
int mx = 1;
for (int i = 1; i < n; i++) {
mx = max(mx, man[i]);
if (i + mx >= n)
continue;
auto lh = hash.substr_hash(i - mx, i);
auto rhl = hrash.substr_hash(n - i - man[i] - 1, n - i - 1), rhr = hrbsh.substr_hash(n - i - mx + 1, n - i - man[i]);
pair<int, int> rh{ (rhl.first + 1LL * rhr.first * hash.pow1[man[i] + 1] % mod1) % mod1,(rhl.second + 1LL * rhr.second * hash.pow2[man[i] + 1] % mod2) % mod2 };
if (lh.first != rh.first || lh.second != rh.second)
continue;
int d = mx + 1;
while (i - d >= 0 && n - i - d + 1 >= 0 && aa[i - d] == rbb[n - i - d + 1])
d++;
mx = max(mx, d - 1);
}
return mx;
}
int main() {
read<int>();
string a, b;
cin >> a >> b;
auto ra = a, rb = b;
reverse(ra.begin(), ra.end());
reverse(rb.begin(), rb.end());
cout << max(solve(a, b), solve(rb, ra));
return 0;
}