目錄題目傳送門
其實是manacher的題目,但是也是可以用回文自動機做的。構建出回文自動機之後,就可以在回文數上進行dp,如果乙個點代表的回文串的長度為4的倍數,並且存在長度為它一半的字尾,就是乙個滿足答案的回文串。關鍵就在於如何判斷是否有長度為它一半的字尾。我們通過回文自動機可以構建出\(fail\)樹,然後在\(fail\)樹上,乙個節點的父親節點必定是他的子串,所以我們進行\(dfs\),並且記錄每種長度的子串出現的次數,就可以判斷是否有長度一半的回文子串。
#include using namespace std;
typedef long long ll;
bool finish_read;
templateinline void read(t &x)while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;finish_read=1;}
templateinline void print(t x)
templateinline void writeln(t x)
templateinline void write(t x)
/****************=header template**********====*/
const int maxn=5e5+500;
int res=0;
int edcnt,n;
char s[maxn];
/****************===define area***************=*/
struct linee[maxn];
int h[maxn],cnt=1;
inline void addedge(int u,int v);h[u]=cnt++;}
struct pldtree t[maxn];
int vis[maxn];
int last,tot;
void init()
void insert(int c,int n,char *s)
last=t[p].son[c];
} void dfs(int u)
--vis[t[u].len];
}}t;
int main()
bzoj 2342 雙倍回文 回文自動機
定義雙倍回文串的左一半和右一半均是回文串的長度為4的倍數的回文串 求乙個給定字串中最長的雙倍回文串的長度 我們知道可以簡單地判定以某一點結尾的最長回文串 我們知道可以簡單地判定以某一點開頭的最長回文串 啥?第二個?你把串倒過來不就行了?所以我們列舉雙倍回文串的斷點再判定即可.我們發現我們每次都要取列...
BZOJ2342 雙倍回文(回文自動機 樹上差分)
題面 題意 給你乙個串,求出它的最長子串 滿足該子串有兩個長度相等且為偶數的回文串拼接而成 該串顯然是回文串,就對應回文自動機上的乙個狀態 若某個狀態的長度為4的倍數 且存在某個祖先的長度為其一半 則該狀態可以貢獻答案 因為祖先即回文字尾和字首 長度為其一半的字首和字尾都是回文串 顯然符合題意 我的...
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 ...