題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5421
思路:同時維護收尾兩個last可以實現首尾同時插入,需要注意的是當插入過後最長迴文串是當前整個字符串,要把另一個last的值設爲當前這個last的值
#pragma GCC optimize(2)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1e9+7)
#define pb push_back
#define eps 1e-6
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
const int N=3e5+8;
int x,n;
char a;
struct PAM{
struct node{
int len,fail,son[26],siz;
void init(int _len=0){
memset(son,0,sizeof(son));
fail=siz=0;
len=_len;
}
}tr[N];
int s[N];
ll num,last[2],ans,l,r;
void init()
{
last[0]=last[1]=ans=0;num=1;
l=100008,r=100007;
tr[0].init();
REW(s,-1);
tr[1].init(-1);
tr[0].fail=1;
}
int getfail(int x,int d)
{
if(d) while(s[r-tr[x].len-1]!=s[r]) x=tr[x].fail;
else while(s[l+tr[x].len+1]!=s[l]) x=tr[x].fail;
return x;
}
void extend(int x,int d)
{
if(d) s[++r]=x;
else s[--l]=x;
int cur=getfail(last[d],d);
int now=tr[cur].son[x];
if(!now)
{
now=++num;
tr[now].init(tr[cur].len+2);
tr[now].fail=tr[getfail(tr[cur].fail,d)].son[x];
tr[now].siz=tr[tr[now].fail].siz+1;
tr[cur].son[x]=now;
}
last[d]=now;
if(r-l+1==tr[now].len) last[d^1]=now;
ans+=1ll*tr[now].siz;
}
}A,B;
int main()
{
cin.tie(0);
cout.tie(0);
while(si(n)!=EOF)
{
A.init();
while(n--)
{
si(x);
if(x==1) scanf(" %c",&a),A.extend(a-'a',0);
else if(x==2) scanf(" %c",&a),A.extend(a-'a',1);
else if(x==3) printf("%lld\n",A.num-1);
else printf("%lld\n",A.ans);
}
}
return 0;
}