1. 程式人生 > >[學習筆記]線性代數 - 迴文自動機

[學習筆記]線性代數 - 迴文自動機

題目大意:每次往左/右加一個字元,問迴文串和本質不同的迴文串數量。
迴文自動機模板題。

#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; }