SAM的下标我一直都是从0开始,结果带入LCT就挂了,而且蜜汁MLE,找了好久才发现,交了好多遍
/**************************************************************
Problem: 2555
User: Clare
Language: C++
Result: Accepted
Time:15276 ms
Memory:161280 kb
****************************************************************/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
#define N 1200010
int n,m,Mask;
char S[3000010],op[10];
struct LCT{
int fa[N],c[N][2],flag[N],v[N];
stack<int> st;
bool Pd_root(int k)
{
return !(c[fa[k]][0]==k)&&!(c[fa[k]][1]==k);
}
void Pushdown(int k)
{
int l=c[k][0],r=c[k][1];
if(flag[k]!=0)
{
flag[l]+=flag[k];flag[r]+=flag[k];
v[l]+=flag[k];v[r]+=flag[k];
flag[k]=0;
}
}
void Rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(c[y][0]==x)l=0;else l=1;
r=l^1;
if(Pd_root(y));
else c[z][c[z][1]==y]=x;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
}
void Splay(int x)
{
st.push(x);
for(int i=x;!Pd_root(i);i=fa[i])
st.push(fa[i]);
while(!st.empty())
{
int now=st.top();st.pop();
Pushdown(now);
}
while(!Pd_root(x))
{
int y=fa[x],z=fa[y];
if(!Pd_root(y))
{
if(c[y][0]==x^c[z][0]==y)
Rotate(x);
else Rotate(y);
}
Rotate(x);
}
}
void Access(int x)
{
for(int i=0;x;i=x,x=fa[x])
Splay(x),c[x][1]=i;
}
void Move_to_root(int x)
{
Access(x);Splay(x);
}
void Join(int x,int y)
{
fa[x]=y;Move_to_root(y);
flag[y]+=v[x];
v[y]+=v[x];
}
void Cut(int x)
{
Move_to_root(x);
flag[c[x][0]]-=v[x];v[c[x][0]]-=v[x];
fa[c[x][0]]=0;c[x][0]=0;
}
}t;
struct SAM{
int fa[N],son[N][26];
int val[N];
int tot,root,last,p,np,q,nq;
void Init()
{
tot=0;last=root=++tot;
}
void Insert(int w)
{
p=last,np=++tot;val[np]=val[p]+1;
t.v[np]=1;
while(p&&!son[p][w])
son[p][w]=np,p=fa[p];
if(!p)
fa[np]=root,t.Join(np,root);
else
{
q=son[p][w];
if(val[q]==val[p]+1)
fa[np]=q,t.Join(np,q);
else
{
nq=++tot;val[nq]=val[p]+1;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q];t.Join(nq,fa[q]);
fa[q]=fa[np]=nq;t.Cut(q);t.Join(q,nq);t.Join(np,nq);
while(p&&son[p][w]==q)
son[p][w]=nq,p=fa[p];
}
}
last=np;
}
void Change_mask(char *str,int mask)
{
int len=(int)strlen(str);
for(int i=0;i<len;i++)
{
mask=(mask*131+i)%len;
char t=str[i];
str[i]=str[mask];
str[mask]=t;
}
}
void Get_in(char *str)
{
Change_mask(str,Mask);
int len=(int)strlen(str);
for(int i=0;i<len;i++)
Insert(str[i]-'A');
}
int Query(char *str)
{
Change_mask(str,Mask);
int len=(int)strlen(str),now=root;
for(int i=0;i<len;i++)
if(son[now][str[i]-'A'])
now=son[now][str[i]-'A'];
else return 0;
t.Splay(now);
return t.v[now];
}
}A;
int main()
{
int Q;scanf("%d",&Q);
A.Init();
scanf("%s",S);
int len=(int)strlen(S);
for(int i=0;i<len;i++)
A.Insert(S[i]-'A');
while(Q--)
{
scanf("%s",op);scanf("%s",S);
if(op[0]=='A')
A.Get_in(S);
else
{
int Ans=A.Query(S);
printf("%d\n",Ans);
Mask^=Ans;
}
}
return 0;
}