*题解:P10271 漫长悄悄话
解析
先手玩一下看看 \(\operatorname{LCP}(\operatorname{Rev}(\operatorname{lcs}(i,j)),\operatorname{lcp}(i,j))\) 是什么。首先长度为 \(x\) 的 \(\operatorname{Rev}(\operatorname{lcs}(i,j))\) 有 \(S_i = S_j,S_{i - 1} = S_{j - 1},\dots S_{i - x + 1} = S_{j - x + 1}\);长度为 \(y\) 的 \(\operatorname{lcp}(i,j)\) 有 \(S_i = S_j,S_{i + 1} = S_{j + 1},\dots,S_{i + y - 1} = S_{j + y - 1}\);最后长度为 \(z\) 的 \(\operatorname{LCP}(\operatorname{Rev}(\operatorname{lcs}(i,j)),\operatorname{lcp}(i,j))\) 有 \(S_{i - 1} = S_{i + 1},S_{i - 2} = S_{i + 2},\cdots,S_{i - z + 1} = S_{i + z - 1}\) 和 \(S[i - z + 1,i + z - 1] = S[j - z + 1,j + z - 1]\)。
于是可以发现,题目要求的就是出现过至少两次的奇长度回文串的半径。
考虑 Manacher,先求出每个位置能扩展的最大长度。然后由于长的回文串内部包含着短的回文串,所以考虑二分答案对应的回文串长度,按照这个长度遍历整个串,对于可扩展长度大于等于 \(mid\) 的位置求 hash,\(O(\log n)\) 统计是否有重复出现的 hash 值即可。
时间复杂度 \(O(n\log^2 n)\)。
代码
/*
*/
#include <bits/stdc++.h>
#define eps 0.0000000001
#define ls(x) ((x) << 1)
#define rs(x) (((x) << 1) | 1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 2e6 + 5,M = 5e5 + 5,P = 2000000,mod1 = 998244353,mod2 = 1e9 + 7,b1 = 131,b2 = 13331;
int len[N];
int h1[N],h2[N],mi1[N],mi2[N];
pii get(int l,int r){
return make_pair((h1[r] + mod1 - 1ll * h1[l - 1] * mi1[r - l + 1] % mod1) % mod1,(h2[r] + mod2 - 1ll * h2[l - 1] * mi2[r - l + 1] % mod2) % mod2);
}
int n;
string t;
bool chk(int x){
vector<pii> v;
for(int i=2;i<t.size();i += 2)if(t[i] >= 'a' && t[i] <= 'z'){
if(len[i] >= x){
v.push_back(get(i - x + 1,i + x - 1));
}
}
sort(v.begin(),v.end());
for(int i=1;i<v.size();i++){
if(v[i] == v[i - 1]) return true;
}
return false;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
mi1[0] = mi2[0] = 1;
for(int i=1;i<N;i++){
mi1[i] = 1ll * mi1[i - 1] * b1 % mod1;
mi2[i] = 1ll * mi2[i - 1] * b2 % mod2;
}
cin>>n;
string s;
cin>>s;
t = "!";
for(int i=0;i<s.size();i++){
t.push_back('#');
t.push_back(s[i]);
}
t += "#?";
for(int i=1;i<t.size();i++){
h1[i] = (1ll * h1[i - 1] * b1 % mod1 + t[i]) % mod1;
h2[i] = (1ll * h2[i - 1] * b2 % mod2 + t[i]) % mod2;
}
int r = 0,c = 0;
for(int i=2;i<t.size() - 1;i++){
int p = 0;
if(r > i){
p = min(r - i,len[c - (i - c)]);
}
while(t[i - p - 1] == t[i + p + 1]) p++;
if(i + p > r){
r = i + p;
c = i;
}
len[i] = p;
}
vector<int> num;
for(int i=1;i<=n;i += 2){
num.push_back(i);
}
int l = 0;r = n / 2;
int res = 0;
while(l < r){
int mid = (l + r + 1) >> 1;
if(chk(mid * 2 + 1)){
l = mid;
res = mid * 2 + 1;
}else{
r = mid - 1;
}
}
if(l == 0 && chk(1)){
res = 1;
}
cout<<(res + 1) / 2;
return 0;
}

浙公网安备 33010602011771号