E. String Multiplication
分析:
从后往前考虑字符串变成什么样子。
设$S_i = p_1 \cdot p_2 \dots p_{i}$,最后一定是$S_{n - 1} \cdot p_n$,就是将$S_{n-1}$每两个字符之间放入$p_n$。按照$p_n$分类讨论,那么最后有三种情况。
设$p_n$的开头字符是$c0$,结尾字符是$c1$,包含开头的连续段的长度是$len0$,包含结尾的连续段的长度是$len1$。
1、$c0 \neq c1$,那么答案可以是三个:(1).可以是$p_n$中最长的连续子段;(2).如果$S_{n-1}$中存在$c0$,$len0+1$;(3).如果$S_{n-1}$中存在$c1$,$len1+1$。
2、$c0 = c1$,并且整个串不只有一种字符:如果$S_{n-1}$中存在$c0$,那么答案可以是$len0+len1+1$
3、如果$p_n$只有一种字符构成,那么求$S_{n-1}$中最长的字符是$c0$连续段的,设为t,答案是$(t+1) \times len + t$。
可以递归查询。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
string s[N];
bool a[N][], b[N]; LL dfs(int x,char c) {
if (x == ) return ;
int ans = a[x - ][c - 'a'], sz = s[x].size();
if (b[x] && s[x][] == c) {
ans = dfs(x - , c);
return (ans + ) * sz + ans;
}
else {
int q = , h = , last = -;
for (int i = ; i < sz; ++i) {
if (s[x][i] == c && last == -) last = i;
if (s[x][i] == c) ans = max(ans, i - last + );
else last = -;
}
for (int i = ; i < sz; ++i) {
if (s[x][i] == c) q ++; else break;
}
for (int i = sz - ; ~i; --i) {
if (s[x][i] == c) h ++; else break;
}
if (s[x][] == c && s[x - ][sz - ] == s[x][] && a[x - ][c - 'a']) ans = max(ans, q + h + );
if (s[x][] == c && a[x - ][c - 'a']) ans = max(ans, q + );
if (s[x][sz - ] == c && a[x - ][c - 'a']) ans = max(ans, h + );
if (s[x][] == c) ans = max(ans, q);
if (s[x][sz - ] == c) ans = max(ans, h);
return ans;
}
}
int main() {
int n = read();
for (int i = ; i <= n; ++i) cin >> s[i], b[i] = ;
for (int i = ; i <= n; ++i) {
for (int j = ; j < (int)s[i].size(); ++j) if (s[i][j] != s[i][j - ]) { b[i] = ; break; }
for (int j = ; j < (int)s[i].size(); ++j) a[i][s[i][j] - 'a'] = ;
for (int j = ; j < ; ++j) a[i][j] |= a[i - ][j];
}
int ans = , q = , h = , last = , sz = s[n].size();
for (int i = ; i < sz; ++i) {
if (last == && s[n][i] == s[n][]) q ++;
if (s[n][i] == s[n][last]) ans = max(ans, i - last + );
else last = i;
}
for (int i = sz - ; i >= ; --i) {
if (s[n][i] == s[n][sz - ]) h ++;
else break;
}
if (!b[n]) {
if (s[n][] == s[n][sz - ] && a[n - ][s[n][] - 'a']) ans = max(ans, q + h + );
if (a[n - ][s[n][] - 'a']) ans = max(ans, q + );
if (a[n - ][s[n][sz - ] - 'a']) ans = max(ans, h + );
ans = max(ans, max(q, h));
cout << ans;
return ;
}
int t = dfs(n - , s[n][]);
cout << (t + ) * sz + t;
return ;
}