您的位置:首页 > 其它

bzoj2555

2016-06-01 19:34 211 查看
开始时间:19:40

完成时间:21:00

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555

题目大意:(1):在当前字符串的后面插入一个字符串

    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 1200005
#define maxl 3000005
using namespace std;
int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn];
char st[maxl];
char ss[20];
struct data{
int fa[maxn],son[maxn][2];
int isroot(int x) {return (son[fa[x]][0]!=x && son[fa[x]][1]!=x);}
int which(int x){return son[fa[x]][1]==x;}
void change(int x,int k){ ri[x]+=k; lazy[x]+=k;}
void pushdown(int x)
{
if (!lazy[x]) return;
if (son[x][1]) change(son[x][1],lazy[x]);
if (son[x][0]) change(son[x][0],lazy[x]);
lazy[x]=0;
}
void relax(int x){if (!isroot(x)) relax(fa[x]); pushdown(x);}
void turn(int x){
int y=fa[x],wx=which(x),wy=which(y);
if (!isroot(y)) son[fa[y]][wy]=x; fa[x]=fa[y];
son[y][wx]=son[x][1-wx]; fa[son[x][1-wx]]=y;
son[x][1-wx]=y; fa[y]=x;
}
void splay(int x)
{
relax(x);
while (!isroot(x))
{
if (isroot(fa[x])) turn(x);
else if (which(x)==which(fa[x])) turn(fa[x]),turn(x);
else turn(x),turn(x);
}
}
void access(int x)
{
for (int p=0; x; x=fa[x]){ splay(x); son[x][1]=p; p=x;}
}
void link(int x,int y){
fa[x]=y; access(y); splay(y); change(y,ri[x]);
}
void cut(int x)
{
access(x); splay(x); change(son[x][0],-ri[x]); fa[son[x][0]]=0; son[x][0]=0;
}
}lct;
struct date{
int fa[maxn],son[maxn][26],val[maxn];
void prepare(){root=tot=last=1;}
int newnode(int x){val[++tot]=x; return tot;}
void extend(int x)
{
int p=last,np=newnode(val[p]+1);ri[np]=1;last=np;
for (; p&&!son[p][x]; p=fa[p]) son[p][x]=np;
if (!p) fa[np]=root,lct.link(np,root);
else
{
int q=son[p][x];
if (val[q]==val[p]+1){fa[np]=q; lct.link(np,q);}
else
{
int nq=newnode(val[p]+1);ri[nq]=0;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; lct.cut(q),lct.link(nq,fa[nq]);
fa[q]=fa[np]=nq; lct.link(q,nq),lct.link(np,nq);
for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq;
}
}
}
void build()
{for (int i=1; i<=m; i++) extend(st[i]-'A');}
void query(){
int x,y;
bool can=1;
x=root;
for (int i=1;i<=m;i++){
y=st[i]-'A';
if (!son[x][y]){
can=0;
break;
}else{
x=son[x][y];
}
}
if (can==0||x==root) puts("0");
else{
lct.splay(x);
printf("%d\n",ri[x]),mark^=ri[x];
}
}
}SAM;
void unzip(){
int temp=mark;
for (int i=1;i<=m;i++){
temp=(temp*131+i-1)%m+1;
char t=st[i]; st[i]=st[temp],st[temp]=t,temp--;
}
}
int main()
{
scanf("%d\n",&q);mark=0;
scanf("%s",st+1); m=strlen(st+1);
SAM.prepare();
SAM.build();
for (int i=1; i<=q; i++)
{
scanf("%s",ss);scanf("%s",st+1); m=strlen(st+1);unzip();
if (ss[0]=='A') SAM.build();
else SAM.query();
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: