【bzoj2342】[Shoi2011]雙倍迴文
阿新 • • 發佈:2018-11-19
題目連結
發現部落格裡沒有迴文樹的板子
所以寫一道**題來補一下(話說我之前都沒補嗎
被學長嘲諷部落格裡都是模板(我的部落格就是用來存模板的ya hahahahahhaa
這題就是瞎搞
不用想太多直接瞎搞
迴文樹建出來
問題就轉化成對於
每個長度為4的倍數、且fail樹上存在一個父親的長度為自身長度的一半的節點的長度最大值
就是這樣了,dfs一下就好
程式碼:
#include<cstdio> #include<vector> #include<queue> #include<ctime> #include<algorithm> #include<cstdlib> #include<stack> #include<cstring> #include<cmath> using namespace std; typedef long long LL; const int INF = 2147483647; const int maxn = 500010; char s[maxn]; vector<int> e[maxn]; int n,ans,tot,now,last,cnt[maxn]; int fa[maxn],len[maxn],ch[maxn][30]; inline LL getint() { LL ret = 0,f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar(); return ret * f; } inline int getfail(int x) { while (s[now] != s[now - len[x] - 1]) x = fa[x]; return x; } inline void init() { len[tot = 1] = -1; len[last = 0] = 0; fa[0] = 1; s[0] = '%'; } inline void add(int x) { int cur = getfail(last); if (!ch[cur][x]) { int p = ++tot; len[p] = len[cur] + 2; fa[p] = ch[getfail(fa[cur])][x]; ch[cur][x] = p; } last = ch[cur][x]; } inline void dfs(int u) { if (len[u] % 4 == 0 && cnt[len[u] >> 1]) ans = max(ans,len[u]); if (u != 1 && u != 0) cnt[len[u]]++; for (int i = 0; i < e[u].size(); i++) dfs(e[u][i]); if (u != 1 && u != 0) cnt[len[u]]--; } int main() { #ifdef AMC freopen("AMC1.txt","r",stdin); #endif n = getint(); scanf("%s",s + 1); init(); for (now = 1; now <= n; now++) add(s[now] - 'a' + 1); for (int i = 0; i <= tot; i++) if (i != 1) e[fa[i]].push_back(i); ans = 0; dfs(1); printf("%d",ans); return 0; }