-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathPalTree2.cpp
45 lines (45 loc) · 1.36 KB
/
PalTree2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// len[s]是對應的回文長度
// num[s]是有幾個回文後綴
// cnt[s]是這個回文子字串在整個字串中的出現次數
// fail[s]是他長度次長的回文後綴,aba的fail是a
const int MXN = 1000010;
struct PalT{
int nxt[MXN][26],fail[MXN],len[MXN];
int tot,lst,n,state[MXN],cnt[MXN],num[MXN];
int diff[MXN],sfail[MXN],fac[MXN],dp[MXN];
char s[MXN]={-1};
int newNode(int l,int f){
len[tot]=l,fail[tot]=f,cnt[tot]=num[tot]=0;
memset(nxt[tot],0,sizeof(nxt[tot]));
diff[tot]=(l>0?l-len[f]:0);
sfail[tot]=(l>0&&diff[tot]==diff[f]?sfail[f]:f);
return tot++;
}
int getfail(int x){
while(s[n-len[x]-1]!=s[n]) x=fail[x];
return x;
}
int getmin(int v){
dp[v]=fac[n-len[sfail[v]]-diff[v]];
if(diff[v]==diff[fail[v]])
dp[v]=min(dp[v],dp[fail[v]]);
return dp[v]+1;
}
int push(){
int c=s[n]-'a',np=getfail(lst);
if(!(lst=nxt[np][c])){
lst=newNode(len[np]+2,nxt[getfail(fail[np])][c]);
nxt[np][c]=lst; num[lst]=num[fail[lst]]+1;
}
fac[n]=n;
for(int v=lst;len[v]>0;v=sfail[v])
fac[n]=min(fac[n],getmin(v));
return ++cnt[lst],lst;
}
void init(const char *_s){
tot=lst=n=0;
newNode(0,1),newNode(-1,1);
for(;_s[n];) s[n+1]=_s[n],++n,state[n-1]=push();
for(int i=tot-1;i>1;i--) cnt[fail[i]]+=cnt[i];
}
}palt;