题面链接 :https://codeforces.com/contest/1131/problem/E
题解 :
p1p2p3…pn=p1*(p2*(p3*(…(pn-1*pn))))
注意到从pn乘到p1时ans是单调不减的
所以我们可以从最后一个字符串向前递推。我们用L表示当前字符串积(pipi+1…pn)的最长相等前缀,用R表示当前当前字符串积的最长相等后缀。ans表示当前的答案。再考虑到pi-1的时候,我们只要维护上面三个值就行了。注意考虑字符串有所有字符都相等的情况。
具体看代码。
code :
#include <bits/stdc++.h>
using namespace std;
const int maxn=200010;
char lc[maxn],rc[maxn],s[maxn];
int l[maxn],r[maxn],pz[maxn],cnt[maxn][27];
int main()
{
int n,i,now,j,len,ans,L,R,flag,num;
char l0,r0;
scanf("%d",&n);
memset(cnt,0,sizeof(cnt));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for (i=1;i<=n;i++) {
scanf("%s",s+1);
len=strlen(s+1);
lc[i]=s[1]; rc[i]=s[len];
now=2;
while (now<=len&&s[now]==s[now-1]) now++;
now--; l[i]=now;
if (now>=len) r[i]=l[i];
else {
now=len-1;
while (now>=1&&s[now]==s[now+1]) now--;
now++;
r[i]=len-now+1;
}
if (l[i]+r[i]>len) {
pz[i]=1;
}else pz[i]=0;
now=1;
cnt[i][s[1]-'a']=1;
for (j=2;j<=len;j++) {
if (s[j]==s[j-1]) {
now++;
}else {
cnt[i][s[j-1]-'a']=max(cnt[i][s[j-1]-'a'],now);
now=1;
}
}
cnt[i][s[len]-'a']=max(cnt[i][s[len]-'a'],now);
if (i==n) {
l0=s[1]; r0=s[len];
}
}
ans=0;
flag=pz[n];
for (i=0;i<26;i++) {
ans=max(ans,cnt[n][i]);
}
L=l[n]; R=r[n];
if (l0==r0) {
for (i=n-1;i>=1;i--) {
if (flag) {
L=ans*(1+(lc[i]==l0)*l[i])+(lc[i]==l0)*l[i];
R=ans*(1+(rc[i]==r0)*r[i])+(rc[i]==r0)*r[i];
num=(cnt[i][l0-'a']+1)*ans+cnt[i][l0-'a'];
ans=max(ans,L); ans=max(ans,R);
ans=max(ans,num);
if (!pz[i]||l0!=lc[i]) flag=0;
}else {
ans=max(ans,(cnt[i][l0-'a']>=1)*(L+R+1));
}
}
}else {
for (i=n-1;i>=1;i--) {
ans=max(ans,(cnt[i][l0-'a']>=1)+L);
ans=max(ans,(cnt[i][r0-'a']>=1)+R);
}
}
printf("%d\n",ans);
return 0;
}