回文自動機

2021-09-25 14:35:39 字數 1857 閱讀 3589

乙個節點表示乙個回文串。

tot:節點個數,即不同回文串的個數。兩棵樹,節點為0,1,所以最後計數時從2開始

n:新增的字元個數

last:新新增乙個字母後所形成的最長回文串表示的節點

nxt[i][c]:節點i表示的回文串在兩邊新增字元c後變成的回文串編號(兒子)

cnt[i]:節點i表示的本質不同的串的個數,即回文串i的個數(建樹時求出的不是完全的,最後重新統計一遍以後才是正確的)。

len[i]:節點i表示的回文串的長度

fail[i]:節點i失配以後跳轉不等於自身的節點i表示的回文串的最長字尾回文串。

s[i]:第i次新增的字元,開始s[0]=-1

id[i]:記錄節點i表示的回文串的最後乙個字元是第幾個插入的

struct palindromic_tree 

void init()

int get_fail(int x)

void add(int c)

last = nxt[cur][c];

cnt[last]++, id[last] = n;

}ll count()

return 0;

}} pam;

theme:給定字串s,求s的所有回文串h出現的次數與長度之積的最大值。

solution:回文樹。就是板子的cnt[i]*len[i]最大值

//theme:給定字串s,求s的所有回文串h出現的次數與長度之積的最大值。

#includeusing namespace std;

#define pb(x) push_back(x)

#define far(i,t,n) for(int i=t;i= 0; i--) cnt[fail[i]] += cnt[i];

for (int i = 2; i < tot; i++)

return ans;

}} pam;

int main()

typedef long long ll;

typedef unsigned long long ull;

const ull hash1 = 201326611;

const ull hash2 = 50331653;

const int n = 300000 + 10;

const int m = 1000 + 10;

const int inf = 0x3f3f3f3f;

const ll mod = 998244353;

ll ret[n];

ull ha[n], pp[n];

ull getha(int l, int r)

bool check(int l, int r)

struct palindromic_tree

void init()

int get_fail(int x)

void add(int c)

last = nxt[cur][c];

cnt[last]++, id[last] = n;

}ll count()

}return 0;

}} pam;

char str[n];

int main()

while (~scanf("%s", str))

for (int i = 1; i < len; i++)

pam.count();

printf("%lld", ret[1]);

for (int i = 2; i <= len; i++)

printf("\n");

}return 0;

}

回文自動機

回文自動機,又叫回文樹,是由俄羅斯人 mikhailrubinchik於2014年夏發明的 這是一種比較新的資料結構,在原文中已有詳細介紹與 實現。回文樹其實不是嚴格的樹形結構,因為它有是兩棵樹,分別是偶數長度的回文樹和奇數長度的回文樹,樹中每個節點代表乙個回文串。為了方便,第一棵樹的根是乙個長度為...

回文自動機

小小總結 別忘了寫上初始化!當字串下標從0 00開始時,pos pospo s初始化為 1 1 1 若從1 11開始,則pos pospo s初始化為0 00 最終的pos pospo s代表最後乙個字元的下標 前者為n 1 n 1n 1,後者為n nn 根據本質不同的回文子串數量不超過 s s s...

回文自動機

回文樹 回文自動機 他的功能如下 求字首字串中的本質不同的回文串種類 求每個本質不同回文串的個數 以下標每個本質不同回文串包含的本質不同回文串種類 fail fail指標,類似於ac自動機,返回失配後與當前cnt 在最後統計後它可以表示形如以 num 表示以 len 表示以 s 存放新增的字元 n ...