首页 技术 正文
技术 2022年11月19日
0 收藏 394 点赞 4,172 浏览 2464 个字

SAM+LCT维护parent tree版本

虽然说子树维护那套理论需要ETT

不过parent tree的根是固定的,所以用lct加一些奇怪的乱搞就行了

//随手拖个SAM的板子和LCT的板子,然后再加几句话就写完了【手动滑稽

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define ll long long
#define N 1200006using namespace std;
struct LinkCutTree{
#define ls(a) (t[a].c[0])
#define rs(a) (t[a].c[1])
struct LCTnode{
int c[2],fa;
int sum,tag;
} t[N];
void newnode(int x,int value){
ls(x)=rs(x)=t[x].fa=t[x].tag=0;
t[x].sum=value;
}
void Add(int x,int delta){
if (!x) return;
t[x].sum+=delta;t[x].tag+=delta;
}
int f(int x){return (ls(t[x].fa)!=x)*(1-2*(rs(t[x].fa)!=x));}
void PushDown(int x){
if (t[x].tag){
Add(ls(x),t[x].tag);
Add(rs(x),t[x].tag);
t[x].tag=0;
}
}
void rotate(int x){
int y=t[x].fa,z=t[y].fa,k=f(x),fz=f(y);
if (fz>=0) t[z].c[fz]=x;
t[y].c[k]=t[x].c[k^1];t[x].c[k^1]=y;
t[t[y].c[k]].fa=y;t[x].fa=z;t[y].fa=x;
}
int stack[N],top;
void splay(int x){
top=0;stack[top++]=x;
for (int i=x;f(i)>=0;i=t[i].fa) stack[top++]=t[i].fa;
while (top) PushDown(stack[--top]);
for (;f(x)>=0;rotate(x))
if (f(t[x].fa)==f(x)) rotate(t[x].fa);
else if (f(t[x].fa)>=0) rotate(x);
}
void access(int x){
for (int son=0;x;son=x,x=t[x].fa)
splay(x),rs(x)=son;
}
void link(int u,int f){
access(f);splay(f);Add(f,t[u].sum);
t[u].fa=f;
}
void cut(int u){
access(u);splay(u);Add(ls(u),-t[u].sum);
ls(u)=t[ls(u)].fa=0;
}
int getsum(int u){
splay(u);return t[u].sum;
}
} pt;struct SAM{
struct SAMnode{
int par,mx,go[26];
SAMnode(){}
SAMnode(int _mx):par(0),mx(_mx){
memset(go,0,sizeof(go));
}
} t[N];
int last,size;
int newnode(int _mx,int value){
t[++size]=SAMnode(_mx);
pt.newnode(size,value);
return size;
}
void clear(){size=0;last=newnode(0,0);}
void extend(char c){
c-='A';
int p=last,np=newnode(t[p].mx+1,1);
for (;p&&!t[p].go[c];p=t[p].par) t[p].go[c]=np;
if (!p) t[np].par=1,pt.link(np,1);
else{
int q=t[p].go[c];
if (t[p].mx+1==t[q].mx) t[np].par=q,pt.link(np,q);
else{
int nq=newnode(t[p].mx+1,0);
memcpy(t[nq].go,t[q].go,sizeof(t[q].go));
t[nq].par=t[q].par;pt.link(nq,t[q].par);
t[np].par=nq;pt.link(np,nq);
pt.cut(q);t[q].par=nq;pt.link(q,nq);
for (;p&&t[p].go[c]==q;p=t[p].par) t[p].go[c]=nq;
}
}
last=np;
}
int solve(char *s){
int p=1;
for (int i=0;p&&s[i];++i) p=t[p].go[s[i]-'A'];
if (!p) return 0;
return pt.getsum(p);
}
} sam;void decode(char *s,int mask){
int l=strlen(s);
for (int i=0;i<l;++i){
mask=(mask*131+i)%l;
swap(s[i],s[mask]);
}
}char st[N],op[10];
int main(){
int Q;scanf("%d%s",&Q,st);
sam.clear();
for (int i=0;st[i];++i) sam.extend(st[i]);
int mask=0,res;
while (Q--){
scanf("%s%s",op,st);
decode(st,mask);
if (op[0]=='Q'){
printf("%d\n",res=sam.solve(st));
mask^=res;
}
else for (int i=0;st[i];++i) sam.extend(st[i]);
}
return 0;
}

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,083
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,558
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,407
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,180
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,816
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,899