BZOJ2342 雙倍回文

2022-03-31 15:08:23 字數 1133 閱讀 7462

目錄題目傳送門

其實是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 ...