一遍过的人是神。要是会回文树就好了
https://www.lydsy.com/JudgeOnline/problem.php?id=3676
http://uoj.ac/problem/103
据说这题要用回文树?
不会。
于是用了 SAM + Manacher ,
还卡空间卡了几次。
先考虑,如果只是求所有子串的 出现次数×长度 出 现 次 数 × 长 度 之和,那么这是道后缀自动机裸题,答案是:
#include
#include
#include
#include
#include
#define For(i, a, b) for (i = a; i <= b; i++)
#define Rof(i, a, b) for (i = a; i >= b; i--)
#define SAM(pyz) for (; i && pyz; i = T[i].fa)
using namespace std;
typedef long long ll; const int N = 6e5 + 5, LogN = 21;
int n, m, r[N], QAQ, lst, tmp[N]; char s[N], t[N];
int Log[N], RMQ[N][LogN];
void APIO2014() {
int p = 0, mx = 0, i, j; For (i, 1, m) {
r[i] = mx > i ? min(r[(p << 1) - i], mx - i) : 1;
while (t[i - r[i]] == t[i + r[i]]) r[i]++;
if (i + r[i] > mx) mx = i + r[i], p = i; RMQ[i][0] = i + r[i] - 1;
}
Log[0] = -1; For (i, 1, m) Log[i] = Log[i >> 1] + 1;
For (j, 1, 20) For (i, 1, m - (1 << j) + 1)
RMQ[i][j] = max(RMQ[i][j - 1], RMQ[i + (1 << j - 1)][j - 1]);
}
int query(int l, int r) {
int x = Log[r - l + 1]; return max(RMQ[l][x], RMQ[r - (1 << x) + 1][x]);
}
struct cyx {
int fa, ri, maxl, go[26], id;
void init() {fa = ri = maxl = id = 0; memset(go, 0, sizeof(go));}
} T[N];
inline bool comp(const int &a, const int &b) {return T[a].maxl < T[b].maxl;}
void extend(int c) {
int i = lst; T[lst = ++QAQ].init(); T[lst].ri = 1;
T[lst].id = T[lst].maxl = T[i].maxl + 1; SAM(!T[i].go[c]) T[i].go[c] = lst;
if (!i) T[lst].fa = 1; else {
int j = T[i].go[c]; if (T[i].maxl + 1 == T[j].maxl) T[lst].fa = j;
else {
int p; T[p = ++QAQ] = T[j]; T[lst].fa = T[j].fa = p; T[p].ri = 0;
T[p].maxl = T[i].maxl + 1; SAM(T[i].go[c] == j) T[i].go[c] = p;
}
}
}
int qFirst(int l, int r, int x) {
int le = l; while (l <= r) {
int mid = l + r >> 1;
if (query(le, mid) < x) l = mid + 1; else r = mid - 1;
}
return l;
}
ll solve() {
int i; For (i, 1, QAQ) tmp[i] = i; sort(tmp + 1, tmp + QAQ + 1, comp);
Rof (i, QAQ, 1) T[T[tmp[i]].fa].ri += T[tmp[i]].ri;
ll ans = 0; For (i, 2, QAQ) {
int p = T[i].id, le = (p << 1) - T[i].maxl + 1,
ri = (p << 1) - T[T[i].fa].maxl, w = qFirst(le, ri, p << 1);
ans = max(ans, 1ll * ((p << 1) + 1 - w) * T[i].ri);
}
return ans;
}
int main() {
int i; scanf("%s", s + 1); n = strlen(s + 1); t[0] = '%';
T[QAQ = lst = 1].init(); For (i, 1, n) t[++m] = '#', t[++m] = s[i];
t[++m] = '#'; t[m + 1] = '&'; APIO2014(); For (i, 1, n) extend(s[i] - 'a');
cout << solve() << endl; return 0;
}