time limit: 10 sec memory limit: 128 mb
submit: 2820 solved: 1088
[submit][status][discuss]
輸入分為兩行,第一行為乙個整數,表示字串的長度,第二行有個連續的小寫的英文本元,表示字串的內容。
輸出檔案只有一行,即:輸入資料中字串的最長雙倍回文子串的長度,如果雙倍回文子串不存在,則輸出0。16
ggabaabaabaaball
12n<=500000
題意就是要求乙個回文串,這個回文串的一半也是回文串,那麼,可以看出這個串的長度必須是4的倍數。。。。。真心想不出,想了30分鐘,並沒有做出來,對回文自動機的理解還不是很充分,看了題解,大部分用了馬拉車,思維題,但也有充分利用回文自動機的性質;觀察回文自動機上的fail鏈,也就是字尾鏈,它滿足fail鏈連向的節點是這個節點最長的回文字尾,那麼,當整個串都新增進去時,fail鏈也就成了fail樹,連線了所有本質不同的回文串,而且,這個是乙個有向的,由小的串往兩邊新增字元成大的串,所以就可以從根節點0號節點開始dfs,記錄乙個桶,表示長度為i的節點在以前出現過,就只要判斷這個串的長度%4==0,並且長度為len/2的節點在以前出現過,這樣就很好的解決了這個問題;
主要是利用了fail鏈與fail樹的性質,求出雙倍回文!!
1 #include2 #include3 #include4 #include5 #include6 #include7 #include"set"
8 #include"
queue
"9 #include"
vector
"10 #include"
iomanip
"11 #include"
cstring"12
#define inf 1<<29
13#define ll long long
14#define re register
15#define il inline
16#define rep(i,a,b) for(register int i=a;i<=b;++i)
17#define file(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
18using
namespace
std;
19const
int n=26,maxn=500010;20
struct
edgee[maxn];
23int
ans;
24int
head[maxn],num_e;
25 il void link(int x,int
y) 28
struct
palindromic_tree
37 il void
init()
44 il int get_fail(int
x)48 il void add(int
c) 58 lst=nxt[cur][c];59}
60int
t[maxn];
61 il void dfs(int
x) 68
}pam;
69char
ch[maxn];
70 inline int
gi()
77int
main()
SHOI2011 雙倍回文
輸入分為兩行,第一行為乙個整數,表示字串的長度,第二行有個連續的小寫的英文本元,表示字串的內容。輸出檔案只有一行,即 輸入資料中字串的最長雙倍回文子串的長度,如果雙倍回文子串不存在,則輸出0。16 ggabaabaabaaball 12n 500000 首先manacher求出len陣列 我們發現乙...
bzoj 2342 Shoi2011 雙倍回文
題目大意 演算法一 因為雙倍回文串必定是乙個回文串 所以先用manachar求出每個點能夠擴充套件出的最長的回文串長度f i 再列舉對稱軸x,對於y只要滿足y f y x y x f x 2,就可以用len x,y 4來更新答案 對於每個x,只需要用距離其最遠的滿足條件的y來更新即可 將其按i f ...
SHOI2011 bzoj2342 雙倍回文
description input 輸入分為兩行,第一行為乙個整數,表示字串的長度,第二行有個連續的小寫的英文本元,表示字串的內容。output 輸出檔案只有一行,即 輸入資料中字串的最長雙倍回文子串的長度,如果雙倍回文子串不存在,則輸出0。首先由題意可知,只用考慮偶數長的回文串。這樣就不用插入 直...