bzoj 5408: string 后缀自动机 + LCT
联赛前练练码力.
code:
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200006
#define ll long long
#define lson t[x].ch[0]
#define rson t[x].ch[1]
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
struct data
{
int tim,id;
data(int tim=0,int id=0):tim(tim),id(id){}
};
struct node
{
int ch[2],f,val[21],tag[21];
}t[N<<1];
ll sub;
int lastans;
char str[N];
int last,tot,n;
vector<data>G[21];
int ch[N<<1][11],pre[N<<1],len[N<<1],sta[N<<1];
inline int get(int x)
{
return t[t[x].f].ch[1]==x;
}
inline int isrt(int x)
{
return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x);
}
inline void mark(int x,int p,ll v)
{
t[x].val[p]+=v,t[x].tag[p]+=v;
}
void pushdown(int x)
{
if(!x) return;
for(int i=1;i<=n;++i)
{
if(t[x].tag[i])
{
if(lson) mark(lson,i,t[x].tag[i]);
if(rson) mark(rson,i,t[x].tag[i]);
t[x].tag[i]=0;
}
}
}
void rotate(int x)
{
int old=t[x].f,fold=t[old].f,which=get(x);
if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x;
t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old;
t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;
}
void splay(int x)
{
int u=x,fa,v=0;
for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;
for(;v;--v) pushdown(sta[v]);
for(u=t[u].f;(fa=t[x].f)!=u;rotate(x))
if(t[fa].f!=u) rotate(get(fa)==get(x)?fa:x);
}
void Access(int x)
{
for(int y=0;x;y=x,x=t[x].f)
{
splay(x);
rson=y;
}
}
// y 无父亲
void link(int x,int y)
{
t[y].f=x;
}
// x 是 y 的父亲
void cut(int x,int y)
{
Access(y),splay(y);
t[t[y].ch[0]].f=0;
t[y].ch[0]=0;
}
void extend(int id,int c)
{
if(ch[last][c])
{
int p=last;
int q=ch[p][c];
if(len[q]==len[p]+1) last=q;
else
{
int nq=++tot;
len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
cut(pre[q],q);
for(int j=1;j<=n;++j) t[nq].val[j]=t[q].val[j];
link(pre[q],nq);
link(nq,q);
pre[nq]=pre[q],pre[q]=nq;
for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq;
last=nq;
}
}
else
{
int np=++tot,p=last;
len[np]=len[p]+1,last=np;
for(;p&&!ch[p][c];p=pre[p]) ch[p][c]=np;
if(!p) pre[np]=1,link(1,np);
else
{
int q=ch[p][c];
if(len[q]==len[p]+1) pre[np]=q,link(q,np);
else
{
int nq=++tot;
len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
cut(pre[q],q);
for(int j=1;j<=n;++j) t[nq].val[j]=t[q].val[j];
link(pre[q],nq);
link(nq,q);
link(nq,np);
pre[nq]=pre[q],pre[q]=pre[np]=nq;
for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq;
}
}
sub+=len[np]-len[pre[np]];
}
Access(last),splay(last),mark(last,id,1ll);
}
int main()
{
// setIO("input");
int i,j,ty,m;
scanf("%d%d",&n,&ty);
for(tot=i=1;i<=n;++i)
{
scanf("%s",str+1);
int len=strlen(str+1);
for(last=j=1;j<=len;++j) extend(i,str[j]-'0');
G[i].push_back(data(0,last));
}
scanf("%d",&m);
for(i=1;i<=m;++i)
{
int op,x,y,z;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&x,&y);
y=(y^(lastans*1ll*ty))%10;
last=G[x][G[x].size()-1].id;
extend(x,y);
G[x].push_back(data(i,last));
}
if(op==2)
{
scanf("%d%d%d",&x,&y,&z);
int l=0,r=G[x].size()-1,mid=0,pp=0;
while(l<=r)
{
mid=(l+r)>>1;
if(G[x][mid].tim<=y) pp=G[x][mid].id,l=mid+1;
else r=mid-1;
}
Access(pp),splay(pp);
printf("%d\n",lastans=t[pp].val[z]);
}
if(op==3)
{
printf("%lld\n",sub);
}
if(op==4)
{
scanf("%s",str+1);
int len=strlen(str+1),pp=1,flag=0;
for(j=1;j<=len;++j)
{
if(ch[pp][str[j]-'0']) pp=ch[pp][str[j]-'0'];
else { flag=1;break; }
}
// 能匹配
if(!flag)
{
Access(pp);
int best=0;
for(j=1;j<=n;++j) best=max(best,t[pp].val[j]);
lastans=best;
}
else lastans=0;
printf("%d\n",lastans);
}
}
return 0;
}
bzoj 5408: string 后缀自动机 + LCT的更多相关文章
- bzoj 2555 SubString —— 后缀自动机+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 ...
- bzoj 2555: SubString 后缀自动机+LCT
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 688 Solved: 235[Submit][Status][Dis ...
- bzoj 2555 SubString——后缀自动机+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 L ...
- bzoj 2555: SubString【后缀自动机+LCT】
一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的 ...
- BZOJ2555 SubString 【后缀自动机 + LCT】
题目 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 输入 ...
- bzoj2555(后缀自动机+LCT)
题目描述 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 题解 做法很自然,建出后缀自动机,维护每个节点的right ...
- 51nod 1600 Simple KMP【后缀自动机+LCT】【思维好题】*
Description 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i) 显然对于一个字符串,如果我们将每个0<=i&l ...
- bzoj 3277 & bzoj 3473,bzoj 2780 —— 广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...
- 【hihocoder#1413】Rikka with String 后缀自动机 + 差分
搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...
随机推荐
- js光标定位操作
1. 自动选中区域内容 <html> <meta http-equiv="Content-Type" content="text/html; chars ...
- Spring MVC异常处理代码完整实例
Spring MVC异常处理流程: 提供构造方法传值: 配置异常处理器的bean
- (三)pdf的构成之文件头综述
引自:https://blog.csdn.net/steve_cui/article/details/81981943 一般情况下,文件头,即,PDF文件的第一行,它用来定义PDF的版本,从而确定该P ...
- python3+requests:post请求四种传送正文方式
https://www.cnblogs.com/insane-Mr-Li/p/9145152.html 前言:post请求我在python接口自动化2-发送post请求详解(二)已经讲过一部分了,主要 ...
- golang ---网卡信息
package main import ( "fmt" "log" "net" "strings" ) type Net ...
- 【转载】Windows安装Redis并添加本地自启动服务
概况 在windows本地搭建redis缓存,添加到本地计算机的服务中,保证每次开机自动启动服务. 第一步:下载redis(我的是计算机win10,64位) https://github.com/Mi ...
- 异常【kubelet cgroup driver:cgroupfs跟docker cgroup driver:systemd不一致】
修改docker.service vi /lib/systemd/system/docker.service 找到 --exec-opt native.cgroupdriver=systemd \ 修 ...
- springboot笔记08——整合swagger2
Swagger是什么? Swagger是一个RESTFUL 接口的文档在线自动生成和功能测试的框架.利用swagger2的注解可以快速的在项目中构建Api接口文档,并且提供了测试API的功能. Spr ...
- Java知识回顾 (11) 异常处理
距离最近的 Java知识回顾系列(10),2019.4.24日,到现在,已经近半年过去了. 感觉,做一件事情,如果有头无尾,实在不好,心里会一直悬着.所以,现在继续上面的内容. 再次声明,正如(1)中 ...
- 【转载】C#中List集合First和FirstOrDefault方法有何不同
在C#的List集合中查找一个符合条件的元素,一般我们会用First方法或者FirstOrDefault方法来返回第一个符合条件的对象,First方法和FirstOrDefault的调用都是使用Lam ...