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 ...
随机推荐
- JavaScript进行WebSocket字节流通讯示例
websocket进行通讯时,可以选择采用字符串或者字节流的传输模式.但在发送与接收时,需要考虑数据的分包,即分成一个个请求与响应消息.无论是采用哪种传输模式,都不免要遇到这个问题. 采用字符串传输时 ...
- 我的Vue朝圣之路1
1. Vue是什么? 1). 一位华裔前Google工程师开发的前端js库 2). 一个MVVM框架 3). 核心概念 * 数据绑定 ...
- Ubuntu /etc/security/limits.conf 不生效问题
一.问题描述 修改 /etc/security/limits.conf ,重启之后不生效 内容如下: * soft nofile * hard nofile root soft nofile root ...
- 服务端技术选型与考虑(go)
- DataGrip License server
之前用 Resharper 使用 http://xidea.online 来激活 今天下载一个DataGrip 发现不能使用这个地址,不知道是被封杀了还是不能跟 Resharper 的共用 在网上找到 ...
- python3--说简单也不简单的排序算法
在刚开始接触算法时,我们可能一脸懵,不知从何处下手,尤其是现在使用的语言五花八门,各种语言的实现又不尽相同,所以,在这种情况下,千万不能迷失了自己,掌握了算法的原理,就像解数学公式一样,定理给你了,仔 ...
- HTML学习摘要2
DAY 2 HTML 标签可以拥有属性.属性提供了有关 HTML 元素的更多的信息. 属性总是以名称/值对的形式出现,比如:name="value". 属性总是在 HTML 元素的 ...
- MySQL Binlog--基于ROW模式的binlog event大小限制
参数binlog-row-event-max-size:Specify the maximum size of a row-based binary log event, in bytes. Rows ...
- edgex0.7.1_1.0.1的X86编译和交叉编译
一. X86编译 1. 安装zeromq库 根据setup script安装: wget https://github.com/zeromq/libzmq/releases/download/v4.2 ...
- 资源管理与调度系统-YARN的资源调度器
资源管理与调度系统-YARN的资源调度器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 资源调度器是Hadoop YARN中最核心的组件之一,它是ResourceManager中的 ...