bzoj2555: SubString SAM+LCT
来源:互联网 发布:淘宝卖灵符 法律 编辑:程序博客网 时间:2024/04/27 09:44
题目
bzoj2555
Description
懒得写背景了,给你一个字符串init,要求你支持两个操作(1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)你必须在线支持这些操作。
Input
第一行一个数Q表示操作个数第二行一个字符串表示初始字符串init接下来Q行,每行2个字符串Type,Str Type是ADD的话表示在后面插入字符串。Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。为了体现在线操作,你需要维护一个变量mask,初始值为0
读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。询问的时候,对TrueStr询问后输出一行答案Result然后mask = mask xor Result 插入的时候,将TrueStr插到当前字符串后面即可。HINT:ADD和QUERY操作的字符串都需要解压
Output
Sample Input
2AQUERY BADD BBABBBBAAB
Sample Output
0
HINT
40 % 的数据字符串最终长度 <= 20000,询问次数<= 1000,询问总长度<= 10000100 % 的数据字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000新加数据一组--2015.05.20
题意
给定一个初始字符串,支持2个操作。在后面添加一个字符串或询问一个字符串出现了多少次。 强制在线。
字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000。
题解
首先想到的是后缀自动机,每个节点维护一个size,添加一个字符时将它parent的size都加一。询问时沿着后缀自动机走,输出最后一个节点的size即可。
但暴力维护会TLE,于是只能上LCT了。
注意不仅要link新加进来的节点,在后缀自动机构建时parent改变后也要及时link和cut。还有就是复制节点q时所得到的nq的size是为0的(我最初设的是1,wa了好久,其实想想暴力维护时是怎么做的就明白了。),当link q与nq时会将nq的size累加上q的size。
下面贴代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define maxn 1200100char s[3000010];int n,len,ans,mask,last=1,tot=1;struct LCT{ int son[maxn][2],size[maxn],f[maxn],tag[maxn]; #define root(x) (son[f[x]][0]!=x&&son[f[x]][1]!=x) void push_down(int x){ if(tag[x]==0)return; size[son[x][0]]+=tag[x]; tag[son[x][0]]+=tag[x]; size[son[x][1]]+=tag[x]; tag[son[x][1]]+=tag[x]; tag[x]=0; } void push_up(int x){ if(!root(x))push_up(f[x]); push_down(x); } void rt(int x,int k){ int y=f[x],z=f[y]; son[y][k^1]=son[x][k]; f[son[x][k]]=y; son[x][k]=y; f[y]=x; f[x]=z; if(son[z][0]==y)son[z][0]=x; else if(son[z][1]==y)son[z][1]=x; push_down(y); push_down(x); } void splay(int x){ push_up(x); while(!root(x)){ int y=f[x],z=f[y]; if(root(y)&&son[y][0]==x)rt(x,1); else if(root(y)&&son[y][1]==x)rt(x,0); else if(son[z][0]==y&&son[y][0]==x)rt(y,1),rt(x,1); else if(son[z][0]==y&&son[y][1]==x)rt(x,0),rt(x,1); else if(son[z][1]==y&&son[y][0]==x)rt(x,1),rt(x,0); else rt(y,0),rt(x,0); } } void access(int x){ for(int y=0;x;x=f[x]){ splay(x); son[x][1]=y; push_down(x); y=x; } } void link(int x,int y){ access(y);splay(y);f[x]=y; size[y]+=size[x]; tag[y]+=size[x]; } void cut(int x,int y){ access(y); splay(x); f[x]=0; size[y]-=size[x]; tag[y]-=size[x]; } }t;struct SAM{ int go[maxn][26],pre[maxn],step[maxn]; void add(int x){ int p=last,np=++tot; step[np]=step[p]+1; for(;p!=0&&go[p][x]==0;p=pre[p])go[p][x]=np; if(p==0)pre[np]=1; else{ int q=go[p][x]; if(step[q]==step[p]+1)pre[np]=q; else{ int nq=++tot; memcpy(go[nq],go[q],sizeof(go[q])); pre[nq]=pre[q]; t.link(nq,pre[q]); step[nq]=step[p]+1; t.cut(q,pre[q]); pre[q]=pre[np]=nq; t.link(q,nq); for(;go[p][x]==q;p=pre[p])go[p][x]=nq; } } last=np; t.size[last]=1; t.link(last,pre[last]); } int solve(char s[]){ int len=strlen(s),p=1; for(int i=0;i<len;i++){ if(go[p][s[i]-'A']==0)return 0; p=go[p][s[i]-'A']; } t.access(p); t.splay(p); return t.size[p]; }}sam;void trans(int mask){ scanf("%s",s); len=strlen(s); for(int j=0;j<len;j++){ mask=(mask*131+j)%len; char t=s[j]; s[j]=s[mask]; s[mask]=t; }}int main(){ scanf("%d",&n); scanf("%s",s); len=strlen(s); for(int i=0;i<len;i++) sam.add(s[i]-'A'); for(int i=1;i<=n;i++){ scanf("%s",s); if(s[0]=='A'){ trans(mask); len=strlen(s); for(int j=0;j<len;j++) sam.add(s[j]-'A'); }else{ trans(mask); ans=sam.solve(s); printf("%d\n",ans); mask^=ans; } } return 0;}
0 0
- bzoj2555: SubString SAM+LCT
- BZOJ2555【SAM】【LCT】
- 【bzoj2555】SubString LCT+后缀自动机
- BZOJ2555:SubString 后缀自动机 LCT
- [BZOJ2555][LCT][后缀自动机]SubString
- 【bzoj2555】SubString 后缀自动机+LCT
- 后缀自动机 + LCT 【bzoj2555】SubString
- BZOJ2555 SubString 后缀自动机+LCT
- [BZOJ2555]SubString(后缀自动机+lct)
- 【 bzoj 2555 】SubString - LCT SAM
- BZOJ2555:SubString (后缀自动机+(Splay+DFS序/LCT))
- 【BZOJ2555】SubString
- [bzoj2555]SubString
- [bzoj2555]SubString
- 【bzoj2555】SubString
- BZOJ2555: SubString
- bzoj2555: SubString
- bzoj2555 SubString
- Toad for DB2中 双竖线||的作用是什么
- QT creator 中添加gstreamer动态库
- 解决POST数据时因启用Csrf出现的400错误
- 第一天,来开个报道贴
- 深入了解Java之一
- bzoj2555: SubString SAM+LCT
- ssh整合问题:启动tomcat时报错org.springframework.beans.factory.BeanCreationException
- Android 设置圆角虚线
- 蓝桥杯 ALGO-97排序
- C++中四种类型转换方式
- (2-4)HDFS的Java接口,上传,下载,创建文件,删除文件
- 一般情况下的实体设计,Struts2,String,hibernate快速准确的从零开始实现增删改查功能
- bzoj2395: [Balkan 2011]Timeismoney
- R绘图中使用中文字体