OJ-Problems-Source/.ACM-Templates/TXTs/字符串.txt

402 lines
13 KiB
Plaintext
Raw Normal View History

2016-11-22 09:38:35 +08:00
//hash_fun.h
inline size_t __stl_hash_string(const char *s) {
size_t h = 0;
for (; *s; ++s) { h = 5 * h + *s; }
return h;
}
//for hash_map<string, XXX>
struct str_hash {
size_t operator()(const string &str)const {
return __stl_hash_string(str.c_str());
}
};
//BKDR Hash Function
inline size_t BKDRHash(const char *str) {
size_t h = 0, seed = 131; //31 131 1313 13131 131313 etc..
while (*str) { h = h * seed + (*str++); }
return h & 0x7FFFFFFF;
}
//<2F>ַ<EFBFBD><D6B7><EFBFBD>hash
const int N = 20005, P = 31, D = 1000173169;
int n, pp[N] = {1}, hs[N]; char s[N];
int get(int l, int r) { return ((hs[r] - (ll)hs[l - 1] * pp[r - l + 1]) % D + D) % D; }
int main() {
scanf("%d%s", &n, s + 1);
for (int i = 1; i <= n; i++) { pp[i] = pp[i - 1] * P % D; }
for (int i = 1; i <= n; i++) { hs[i] = ((ll)hs[i - 1] * P + s[i]) % D; }
}
//<2F><>дhash_map
const int P = 13131;
char key[N][M];
typedef struct Node { int id, val; } etype;
template<size_t(*Hash)(const char *)> struct hashmap {
vector<etype> hs[P];
void init() { for (int i = 0; i < P; i++) { hs[i].clear(); } }
void insert(int id, int val) {
int h = Hash(key[id]) % P; hs[h].push_back((etype) {id, val});
}
bool erase(char *buf) {
int h = Hash(buf) % P;
for (size_t i = 0; i < n; i++) { if (!strcmp(buf, key[hs[h][i].id])) { hs[h].erase(hs[h].begin() + i); return true; } }
return false;
}
int query(char *buf) {
int h = Hash(buf) % P;
for (size_t i = 0; i < n; i++) { if (!strcmp(buf, key[hs[h][i].id])) { return hs[h][i].val; } }
return false;
}
};
hashmap<BKDRHash> mp;
//Manacher <20><EFBFBD><EEB3A4><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD>
//<2F><EFBFBD><EEB3A4><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD>Ӧԭ<D3A6><D4AD>T<EFBFBD>е<EFBFBD>λ<EFBFBD><CEBB>: l = (i - R[i]) / 2; r = (i + R[i]) / 2 - 2;
char s[N], tmp[N << 1];
int dp[N << 1];
void Manacher(char *s, int len) {
int l = 0, mx = 0, id = 0; tmp[l++] = '$'; tmp[l++] = '#';
for (int i = 0; i < len; i++) { tmp[l++] = s[i]; tmp[l++] = '#'; }
tmp[l] = 0;
for (int i = 0; i < l; i++) {
dp[i] = mx > i ? min(dp[(id << 1) - i], mx - i) : 1;
while (tmp[i + dp[i]] == tmp[i - dp[i]]) { dp[i]++; }
if (i + dp[i] > mx) { mx = i + dp[i]; id = i; }
}
}
int main() {
while (~scanf("%s", s)) {
int len = strlen(s), mlen = (len << 1) + 2, mxlen = 0, mxpos = 0;
Manacher(s, len);
for (int i = 0; i < mlen; i++) {
if (mxlen < dp[i]) { mxlen = dp[i]; mxpos = i; }
}
printf("%d\n", mxlen - 1); //s.substr((mxpos - mxlen) >> 1, mxlen - 1);
}
}
//<2F>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ʾ
int minString(char *s) {
int m = strlen(s), i, j, k;
char ss[m << 1]; strcpy(ss, s); strcpy(ss + m, s);
for (i = k = 0, j = 1; k < m && i < m && j < m;) {
for (k = 0; k < m && ss[i + k] == ss[j + k]; k++);
if (k < m) {
if (ss[i + k] > ss[j + k]) { i += k + 1; } //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<
else { j += k + 1; }
if (i == j) { j++; }
}
}
return min(i, j);
}
//strstr <20><>str1<72>в<EFBFBD><D0B2><EFBFBD>str2<72>ĵ<EFBFBD>һ<EFBFBD>γ<EFBFBD><CEB3><EFBFBD> <20><><EFBFBD>򷵻<EFBFBD>NULL
char *strstr(const char *str1, const char *str2);
//KMP O(M + N)
//nxt[]<5D>ĺ<EFBFBD><C4BA>壺x[i-nxt[i]...i-1]=x[0...nxt[i]-1]
//nxt[i]Ϊ<><CEAA><EFBFBD><EFBFBD>x[i-z...i-1]=x[0...z-1]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zֵ(<28><><EFBFBD><EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>)
char x[N], y[N];
int nxt[N];
void getnxt(char *x, int m, int nxt[]) {
int i = 0, j = -1; nxt[0] = -1;
while (i < m) {
while (j != -1 && x[i] != x[j]) { j = nxt[j]; }
nxt[++i] = ++j;
}
}
//<2F>Ľ<EFBFBD><C4BD><EFBFBD>
void getnxt(char *x, int m, int nxt[]) {
int i = 0, j = -1; nxt[0] = -1;
while (i < m) {
while (j != -1 && x[i] != x[j]) { j = nxt[j]; }
if (x[++i] == x[++j]) { nxt[i] = nxt[j]; }
else { nxt[i] = j; }
}
}
//<2F><><EFBFBD><EFBFBD>x<EFBFBD><78>y<EFBFBD>г<EFBFBD><D0B3>ֵĴ<D6B5><C4B4><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>
//x<><78>ģʽ<C4A3><CABD>, y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int KMPCount(char *x, int m, char *y, int n, int nxt[]/*, int &longest, int &lp*/) {
int i = 0, j = 0, ans = 0; //longest = 0; lp = 0;
while (i < n) {
while (j != -1 && y[i] != x[j]) { j = nxt[j]; }
i++; j++;
//if (j > longest) { longest = j; lp = i - j; }
if (j >= m) { j = nxt[j]; ans++; }
}
return ans;
}
//<2F><>չKMP
//nxt[i]:x[i...m-1]<5D><>x[0...m-1]<5D><><EFBFBD><EFBFBD><EEB3A4><EFBFBD><EFBFBD>ǰ׺
//ext[i]:y[i...n-1]<5D><>x[0...m-1]<5D><><EFBFBD><EFBFBD><EEB3A4><EFBFBD><EFBFBD>ǰ׺
int nxt[N], ext[N];
void getnxt(char *x, int m, int nxt[]) {
int i = 2, j = 0, k = 1;
while (j + 1 < m && x[j] == x[j + 1]) { j++; }
nxt[0] = m; nxt[1] = j;
for (; i < m; i++) {
int p = nxt[k] + k - 1, l = nxt[i - k];
if (i + l < p + 1) { nxt[i] = l; }
else {
j = max(0, p - i + 1);
while (i + j < m && x[i + j] == x[j]) { j++; }
nxt[i] = j; k = i;
}
}
}
void getext(char *x, int m, char *y, int n, int nxt[], int ext[]) {
getnxt(x, m);
int i = 1, j = 0, k = 0;
while (j < n && j < m && x[j] == y[j]) { j++; }
ext[0] = j;
for (; i < n; i++) {
int p = ext[k] + k - 1, l = nxt[i - k];
if (i + l < p + 1) { ext[i] = l; }
else {
j = max(0, p - i + 1);
while (i + j < n && j < m && y[i + j] == x[j]) { j++; }
ext[i] = j; k = i;
}
}
}
//Sunday
int Sunday(char *x, int m, char *y, int n) {
int nxt[26] = {0};
for (int j = 0; j < 26; j++) { nxt[j] = m + 1; }
for (int j = 0; j < m; j++) { nxt[x[j] - 'a'] = m - j; }
for (int pos = 0, i, j; pos <= n - m;) {
for (i = pos, j = 0; j < m; i++, j++) {
if (y[i] != x[j]) { pos += nxt[y[pos + m] - 'a']; break; }
}
if (j == m) { return pos; }
}
return -1;
}
//Rabin-Karp
#define UNSIGNED(x) ((unsigned char)x)
const int d = 257;
int hashMatch(char *s, int m, char *p, int n) {
if (m > n || m == 0 || n == 0) { return -1; }
//svΪs<CEAA>Ӵ<EFBFBD><D3B4><EFBFBD>hash<73><68><EFBFBD><EFBFBD>, pvΪp<CEAA><70>hash<73><68><EFBFBD><EFBFBD>, baseΪd<CEAA><64>m-1<>η<EFBFBD>
unsigned sv = UNSIGNED(s[0]), pv = UNSIGNED(p[0]), base = 1;
int i, j;
//<2F><>ʼ<EFBFBD><CABC>sv, pv, base
for (i = 1; i < m; i++) {
pv = pv * d + UNSIGNED(p[i]);
sv = sv * d + UNSIGNED(s[i]);
base *= d;
}
i = m - 1;
do {
if (!(sv ^ pv)) {
for (j = 0; j < m && s[i - m + 1 + j] == p[j]; j++);
if (j == m) { return i - m + 1; }
}
if (++i >= n) { break; }
//O(1)ʱ<><CAB1><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD>sv, sv + UNSIGNED(s[i - m]) * (~base + 1)<29>ȼ<EFBFBD><C8BC><EFBFBD>sv - UNSIGNED(s[i - m]) * base
sv = (sv + UNSIGNED(s[i - m]) * (~base + 1)) * d + UNSIGNED(s[i]);
} while (i < n);
return -1;
}
//Trie
//<2F><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
struct Trie {
int nxt[N * 20][26], val[N * 20], root, tot;
void init() { memset(nxt, 0, sizeof(nxt)); memset(val, 0, sizeof(val)); root = tot = 1; }
void insert(char *buf, int id) {
int len = strlen(buf), now = root;
for (int i = 0, c; i < len; i++) {
if (!nxt[now][c = buf[i] - 'a']) { nxt[now][c] = ++tot; }
now = nxt[now][c];
}
val[now] = id;
}
int query(char *buf) {
int len = strlen(buf), now = root;
for (int i = 0, c; i < len; i++) {
if (!nxt[now][c = buf[i] - 'a']) { return -1; }
now = nxt[now][c];
}
return val[now];
}
} tr;
//ָ<><D6B8>ʵ<EFBFBD><CAB5>
struct Node { Node *nxt[26]; int val; };
struct Trie {
Node *root;
void init() { erase(root); root = new Node(); }
void insert(char *buf, int id) {
int len = strlen(buf); Node *now = root;
for (int i = 0, c; i < len; i++) {
if (!now->nxt[c = buf[i] - 'a']) { now->nxt[c] = new Node(); }
now = now->nxt[c];
}
now->val = id;
}
void erase(Node *p) {
if (p) { for (int i = 0; i < 26; i++) { erase(p->nxt[i]); } delete p; }
}
int query(char *buf) {
int len = strlen(buf); Node *now = root;
for (int i = 0, c; i < len; i++) {
if (!now->nxt[c = buf[i] - 'a']) { return -1; }
now = now->nxt[c];
}
return now->val;
}
} tr;
//AC<41>Զ<EFBFBD><D4B6><EFBFBD>
struct AC {
int nxt[N * 20][26], fail[N * 20], val[N * 20], root, tot;
void init() { memset(nxt, 0, sizeof(nxt)); memset(val, 0, sizeof(val)); root = tot = 1; }
void insert(char *buf, int id) {
int len = strlen(buf), now = root;
for (int i = 0, c; i < len; i++) {
if (!nxt[now][c = buf[i] - 'a']) { nxt[now][c] = ++tot; }
now = nxt[now][c];
}
val[now] = id;
}
void build() {
queue<int> que; fail[root] = root;
for (int i = 0; i < 26; i++) {
if (!nxt[root][i]) { nxt[root][i] = root; }
else { fail[nxt[root][i]] = root; que.push(nxt[root][i]); }
}
while (!que.empty()) {
int now = que.front(); que.pop();
for (int i = 0; i < 26; i++) {
if (!nxt[now][i]) { nxt[now][i] = nxt[fail[now]][i]; }
else { fail[nxt[now][i]] = nxt[fail[now]][i]; que.push(nxt[now][i]); }
}
}
}
int query(char *buf) {
int len = strlen(buf), now = root, res = 0;
for (int i = 0, c; i < len; i++) {
for (int tmp = now = nxt[now][c = buf[i] - 'a']; tmp != root; tmp = fail[tmp]) {
res += val[tmp]; //val[tmp] = 0;
}
}
return res;
}
} ac;
//<2F><>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>
//n<><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//m<><6D><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>С
//s[0..n - 1]<5D><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
//sa[1..n]<5D><><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD> i С<><D0A1><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>׺
//rnk[0..n - 1]<5D><><EFBFBD><EFBFBD>׺ i <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//height[i]<5D><>lcp(sa[i], sa[i - 1])
int rnk[N], sa[N], height[N], tmp[N], cnt[N];
void SA(char *s, int n, int m) {
int i, j, k; n++;
memset(rnk, 0, sizeof(rnk)); memset(sa, 0, sizeof(sa)); memset(height, 0, sizeof(height));
memset(tmp, 0, sizeof(tmp)); memset(cnt, 0, sizeof(cnt));
for (i = 0; i < n; i++) { cnt[rnk[i] = s[i]]++; }
for (i = 1; i < m; i++) { cnt[i] += cnt[i - 1]; }
for (i = 0; i < n; i++) { sa[--cnt[rnk[i]]] = i; }
for (k = 1; k <= n; k <<= 1) {
for (i = 0; i < n; i++) {
j = sa[i] - k;
if (j < 0) { j += n; }
tmp[cnt[rnk[j]]++] = j;
}
sa[tmp[cnt[0] = 0]] = j = 0;
for (i = 1; i < n; i++) {
if (rnk[tmp[i]] != rnk[tmp[i - 1]] || rnk[tmp[i] + k] != rnk[tmp[i - 1] + k]) { cnt[++j] = i; }
sa[tmp[i]] = j;
}
memcpy(rnk, sa, n * sizeof(int));
memcpy(sa, tmp, n * sizeof(int));
if (j >= n - 1) { break; }
}
for (j = rnk[height[i = k = 0] = 0]; i < n - 1; i++, k++) {
while (k >= 0 && s[i] != s[sa[j - 1] + k]) { height[j] = k--, j = rnk[sa[j] + 1]; }
}
}
//<2F><>׺<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>
const int N = 1000005;
const int N_CHAR = 26;
struct SuffixAutomaton {
struct Node { Node *fail, *next[N_CHAR]; int val, right; };
Node mempool[N << 1]; int n_node;
Node *new_node(int v) {
Node *p = &mempool[n_node++]; memset(p->next, 0, sizeof(p->next));
p->fail = 0; p->right = 0; p->val = v; return p;
}
Node *root, *last;
SuffixAutomaton() { clear(); }
void clear() { root = last = new_node(n_node = 0); }
void add(int c) {
Node *p = last, *np = new_node(p->val + 1);
while (p && !p->next[c]) { p->next[c] = np; p = p->fail; }
if (!p) { np->fail = root; }
else {
Node *q = p->next[c];
if (p->val + 1 == q->val) { np->fail = q; }
else {
Node *nq = new_node(p->val + 1);
for (int i = 0; i < N_CHAR; i++) { nq->next[i] = q->next[i]; }
nq->fail = q->fail; q->fail = np->fail = nq;
while (p && p->next[c] == q) { p->next[c] = nq; p = p->fail; }
}
}
last = np; np->right = 1;
}
Node *go(const char *s) {
Node *p = root; int cL = 0; //<2F><><73><C6A5><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
for (int i = 0; s[i]; i++) {
int c = s[i] - 'a';
if (p->next[c]) { p = p->next[c], ++cL; }
else {
while (p && !p->next[c]) { p = p->fail; }
if (!p) { cL = 0; p = root; }
else { cL = p->val + 1; p = p->next[c]; }
}
}
return p;
}
int d[N << 1]; Node *b[N << 1];
void toposort() {
for (int i = 0; i <= n_node; i++) { d[i] = 0; }
int mx_val = 0;
for (int i = 0; i < n_node; i++) { mx_val = max(mx_val, mempool[i].val); d[mempool[i].val]++; }
for (int i = 1; i <= mx_val; i++) { d[i] += d[i - 1]; }
for (int i = 0; i < n_node; i++) { b[--d[mempool[i].val]] = &mempool[i]; }
}
void updateright() {
toposort();
for (int i = n_node - 1; i; i--) { b[i]->fail->right += b[i]->right; }
}
} sa;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct PalindromicTree {
int nxt[N][26]; //ָ<><D6B8><EFBFBD>Ĵ<EFBFBD>Ϊ<EFBFBD><CEAA>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>˼<EFBFBD><CBBC><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
int fail[N]; //<2F><>ʾʧ<CABE><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ڸô<DAB8><C3B4><EFBFBD><EFBFBD>Ըýڵ<C3BD><DAB5><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EEB3A4><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>ʾ<EFBFBD>Ľڵ<C4BD>
int cnt[N]; //<2F><>ʾ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>ʾ<EFBFBD>ı<EFBFBD><C4B1>ʲ<EFBFBD>ͬ<EFBFBD>Ĵ<EFBFBD><C4B4>ĸ<EFBFBD><C4B8><EFBFBD>(<28><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>, <20><><EFBFBD><EFBFBD>count<6E><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>)
int num[N]; //<2F><>ʾ<EFBFBD>Խڵ<D4BD><DAB5><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EEB3A4><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ˵<D2B6>Ϊ<EFBFBD><CEAA><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>β<EFBFBD>Ļ<EFBFBD><C4BB>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
int len[N]; //<2F><>ʾ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>ʾ<EFBFBD>Ļ<EFBFBD><C4BB>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
int S[N]; //<2F><>ʾ<EFBFBD><CABE>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5>ַ<EFBFBD>(S[0] = -1(<28><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڴ<EFBFBD><DAB4>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ַ<EFBFBD>))
int last; //ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>γɵ<CEB3><C9B5><EFBFBD><EEB3A4><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>ʾ<EFBFBD>Ľڵ<C4BD>
int n; //<2F><>ʾ<EFBFBD><CABE><EFBFBD>ӵ<EFBFBD><D3B5>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
int tot; //<2F><>ʾ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
int newnode(int l) { len[tot] = l; return tot++; }
void init() {
memset(nxt, 0, sizeof(nxt)); memset(cnt, 0, sizeof(cnt)); memset(len, 0, sizeof(len));
newnode(0); newnode(-1); tot = last = n = 0; S[n] = -1; fail[0] = 1;
}
int getfail(int x) { //ʧ<><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB3A4>
while (S[n - len[x] - 1] != S[n]) { x = fail[x]; }
return x;
}
void add(int c) {
c -= 'a'; S[++n] = c;
int cur = getfail(last); //ͨ<><CDA8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>ƥ<EFBFBD><C6A5>λ<EFBFBD><CEBB>
if (!nxt[cur][c]) { //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>û<EFBFBD>г<EFBFBD><D0B3>ֹ<EFBFBD>, ˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µı<C2B5><C4B1>ʲ<EFBFBD>ͬ<EFBFBD>Ļ<EFBFBD><C4BB>Ĵ<EFBFBD>
int now = newnode(len[cur] + 2); //<2F>½<EFBFBD><C2BD>ڵ<EFBFBD>
fail[now] = nxt[getfail(fail[cur])][c]; //<2F><>AC<41>Զ<EFBFBD><D4B6><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>failָ<6C><D6B8>, <20>Ա<EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת
nxt[cur][c] = now; num[now] = num[fail[now]] + 1;
}
cnt[last = nxt[cur][c]]++;
}
void count() {
for (int i = tot - 1; i >= 0; i--) { cnt[fail[i]] += cnt[i]; }
//<2F><><EFBFBD><EFBFBD><EFBFBD>ۼӶ<DBBC><D3B6>ӵ<EFBFBD>cnt, <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>fail[v] = u, <20><>uһ<75><D2BB><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD>ӻ<EFBFBD><D3BB>Ĵ<EFBFBD>
}
} pat;