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 ...
随机推荐
- 【LEETCODE】40、1051. Height Checker
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- Rediskey生命周期管理-key聚合
| 导语 Redis中的数据以k-v的方式组织:为了方便管理key一般具有某些特定的模式:有些key直接是由mysql中的表行数据转化而来:如果要对Redis的key进行生命周期管理,由于Redis的 ...
- swagger 报错:illegal defaultValue null for param type integer
swagger(版本2.9.2) 刷新报错,错误信息如下图: 问题原因: 根据上面这句报错信息,点进去AbstractSerializableParameter.java:412可以看到 源码, @J ...
- 缓存的设计及PHP实现LFU
1. 恒定缓存性能有哪些因素? 命中率.缓存更新策略.缓存最大数据量. 命中率:指请求缓存次数和缓存返回正确结果次数的比例.比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率.如果数据频繁更新, ...
- vue项目启动报错You may use special comments to disable some warnings.
在build/webpack.base.conf.js文件中,注释或者删除掉:...(config.dev.useEslint ? [createLintingRule()] : []),
- GitHub上传文件问题总结
问题一:git warning: LF will be replaced by CRLF in 解决办法 在Git Bash中输入git add .时出现上述语句. 解决办法: 输入以下语句: $ g ...
- HTML5新增元素和移除的元素?
新增元素: 图像Canvas 多媒体video.audio 本地存储localStorage.sessionStorage 语义化更好的内容元素aticle.header.footer.nav.sec ...
- Vscode选中变量高亮问题
前言 vscode的默认变量选中全局高亮根本看不清楚下一个变量高亮在哪...... 如下图. 框的颜色实在是差强人意. 流程 (1)安装插件:highlight-icemode (2)配置插件:打开用 ...
- Java网上学习资料
1.今天查找关于代理模式时找到的两个网站:take control with proxy design pattern
- Nginx配置文件示例
Nginx的配置文件示例:(仅供参考) 强烈建议先将默认的配置文件备份再进行操作! 请根据自己项目的实际路径来配置相关路径! uwsgi配置文件请参考:uwsgi配置文件示例 # For more i ...