[學習筆記]線性代數 - 迴文自動機
阿新 • • 發佈:2018-12-09
題目大意:每次往左/右加一個字元,問迴文串和本質不同的迴文串數量。
迴文自動機模板題。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0' ;while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
#define las(x) ((x)?las1:las0)
const int N=410000,SIG=30;
struct PAM{
int node_cnt,dpt[N],len[N],fa[N],ch[N][SIG],s[N],L,R,las0,las1,tot;lint ans;
inline int new_node(int l,int x=0) { return len[x=++node_cnt] =l,memset(ch[x],0,sizeof ch[x]),fa[x]=dpt[x]=0,tot++,x; }
inline int init(int m) { return node_cnt=-1,new_node(0),new_node(-1),L=m+5,R=L-1,fa[0]=1,ans=tot=las(0)=las(1)=0,0; }
inline int find(int x,int d)
{
if(d) while(s[R]!=s[R-len[x]-1]) x=fa[x];
else while(s[L]!=s[L+len[x]+1]) x=fa[x];
return x;
}
inline int extend(int c,int d)
{
if(d) s[++R]=c;
else s[--L]=c;
int x=find(las(d),d);
if(!ch[x][c])
{
int y=new_node(len[x]+2);
fa[y]=ch[find(fa[x],d)][c];
dpt[y]=dpt[fa[y]]+1;
if(len[y]==R-L+1) las(d^1)=y;
ch[x][c]=y;
}
return ans+=dpt[las(d)=ch[x][c]],0;
}
}p;
char tp[10],qwq[10];
int main()
{
int m=inn();p.init(m);
while(m--)
scanf("%s%s",tp+1,qwq+1),
p.extend(qwq[1]-'a'+1,tp[1]=='r'),
printf("%lld %d\n",p.ans,p.tot);
return 0;
}