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 ...
随机推荐
- 小程序的数据监听 用法和vue中的watch一样====使用通配符监听所有自数据字段的变化
使用通配符监听所有自数据字段的变化
- Spring Cloud--Hystrix服务熔断(线程隔离/服务降级)代码实现
一旦服务阻塞就进行服务降级或线程隔离.要不然就会导致大面积服务的瘫痪,Hystrix就是干这个的,一出现不健康的服务就进行熔断,不阻塞后面线程的执行. 引入依赖: 加注解: 这三个注解可以用一个注解搞 ...
- Spring Cloud--服务的发布与调用示例
[Provider] 引依赖: 启动类上添加注解: 配置文件: [Consumer] 引依赖: 加注解: 配置文件: 调用服务: 方式一(动态获取服务列表): Eureka默认30秒拉取一次服务列表. ...
- vscode 连接远程服务器 sftp
1.在vscode 应用商店搜索 sftp 下载安装 2.ctrl+shift+p 搜索sftp:config 生成sftp.json 3.配置你的服务器信息{ "name": & ...
- CachedThreadPool
/** * <html> * <body> * <P> Copyright 1994 JsonInternational</p> * <p> ...
- java之hibernate之单向的一对多关联映射
这篇主要讲hiberante中的 单向一对多关联映射 1.在应用中,有时候需要从一的一端获取多的一端的数据.比如:查看某个分类下的所有书籍信息:查看某个订单下的所有商品等. 2.在一对多的关联关系中, ...
- c#自制抽奖小程序
#region 第一部分界面设计 ; Button button = new Button(); Image[] images = new Image[N]; PictureBox[] picture ...
- 虹软人脸识别SDK在网络摄像头中的实际应用
目前在人脸识别领域中,网络摄像头的使用很普遍,但接入网络摄像头和人脸识别SDK有一定门槛,在此篇中介绍过虹软人脸识别SDK的接入流程,本文着重介绍网络摄像头获取视频流并处理的流程(红色框内),以下内容 ...
- SQL SERVER-Extendevent检测TempDB增长
--创建Session收集数tempDB增长数据 CREATE EVENT SESSION [Database_Growth_Watchdog] ON SERVER ADD EVENT sqlserv ...
- c# System.Collections接口图