标签:位置 oid amp dtree nbsp scan 题意 line struct
题意:求这样一个回文串S,S = A + B 且 A, B都是回文串。问最长S
题解:建立两颗回文树,一个从前向后插,一个从后向前插,并记录每个位置得到的最长后缀后文。
ps:马拉车的做法待更
const int N = 100005; struct data { int len, fail; int ch[26]; }; struct PldTree { int tot, last; int cnt[N]; char s[N]; data node[N]; void Inite() { tot = last = 1; node[0].fail = 1; node[1].len = -1; } void Insert(int i) { while(s[i] != s[i - node[last].len - 1]) last = node[last].fail; if (!node[last].ch[s[i] - ‘a‘]) { node[++tot].len = node[last].len + 2; cnt[i] = node[tot].len; int tp = node[last].fail; while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail; node[tot].fail = node[tp].ch[s[i] - ‘a‘]; node[last].ch[s[i] - ‘a‘] = tot; last = tot; } else { last = node[last].ch[s[i] - ‘a‘]; cnt[i] = node[last].len; } } }; PldTree T1, T2; inline void upd(int &a, int b) { (a < b) && (a = b); } int main() { T1.Inite(); T2.Inite(); T1.s[0] = T2.s[0] = ‘0‘; scanf("%s", T1.s + 1); int n = strlen(T1.s + 1); Rep(i, 1, n) { T2.s[i] = T1.s[n + 1 - i]; T1.Insert(i); } Rep(i, 1, n) { T2.Insert(i); } int ans = 0; Rep(i, 1, n) upd(ans, T1.cnt[i] + T2.cnt[n - i]); pr(ans); return 0; }
标签:位置 oid amp dtree nbsp scan 题意 line struct
原文地址:https://www.cnblogs.com/zgglj-com/p/9610092.html