就考虑维护一个 gi 表示 [gi,i] 能被删除,且 gi 最大。
先初始化 gi,枚举一个 i,如果 si−1=si,那么 gi=i−1。
其余的 gi 就记 x=gi−1,让 x 去一直跳: x←gx−1,直到 sx−1=si 为止。
感觉每个位置至多被跳到一次啊,为什么要多乘一个字符集?
for ( int i = 1; i <= n; i ++)
if (s[i] == s[i - 1]) g[i] = i - 1;
for ( int i = 1; i <= n; i ++) {
if (g[i]) continue ;
int x = g[i - 1];
while (x) {
if (s[x - 1] == s[i]) {
g[i] = x - 1;
break ;
}
x = g[x - 1];
}
}