动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符。

Solution

考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这个点的 maxlen

那么在这里,当增量添加的时候,如果一个节点有了儿子,那么它就可能成为一个新的 LCP

于是我们在操作父子关系的时候暴力修改一个 bool 数组即可,答案的维护是均摊 \(O(n)\) 的

注意需要对输出 \(0\) 的情况做特判,比如这个例子

aaaabbbbab

输出的结果应该是

0 0 0 0 4 4 4 4 4 4

居然又卡空格

#include <bits/stdc++.h>
using namespace std; const int N = 2000005; int pin=0;
bool b[N];
vector <int> mem; void push(int x) {
b[x]=1;
while(b[pin]) ++pin;
mem.push_back(x);
} void clear() {
for(int x:mem) b[x]=0;
mem.clear();
pin=0;
} struct Suffix_Automata {
int maxlen[N], trans[N][26], link[N], Size, Last;
int t[N], a[N], cnt[N];
Suffix_Automata() { Size = Last = 1; }
void clear() {
for(int i=1;i<=Size;i++) {
maxlen[i]=link[i]=t[i]=a[i]=cnt[i]=0;
memset(trans[i],0,sizeof trans[i]);
}
Size = Last = 1;
}
inline void Extend(int id) {
int cur = (++ Size), p;
maxlen[cur] = maxlen[Last] + 1;
cnt[cur] = 1;
for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur;
if (!p) link[cur] = 1, push(maxlen[1]);
else {
int q = trans[p][id];
if (maxlen[q] == maxlen[p] + 1) link[cur] = q, push(maxlen[q]);
else {
int clone = (++ Size);
maxlen[clone] = maxlen[p] + 1;
for(int i=0;i<26;i++) trans[clone][i] = trans[q][i];
link[clone] = link[q]; push(maxlen[link[q]]);
for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone;
link[cur] = link[q] = clone; push(maxlen[clone]); push(maxlen[clone]);
}
}
Last = cur;
}
} sam;
char str[N];
int buc[26],tot;
signed main() {
int T;
scanf("%d",&T);
while(T--) {
tot=0;memset(buc,0,sizeof buc);
scanf("%s",str+1);
sam.clear();
int len=strlen(str+1);
for(int i=1;i<=len;i++) {
if(buc[str[i]-'a']==0) ++tot;
buc[str[i]-'a']++;
sam.Extend(str[i]-'a');
printf("%d%s",(tot>1)*pin,i==len?"":" ");
}
puts("");
clear();
}
}

Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机的更多相关文章

  1. Wannafly Camp 2020 Day 3I N门问题 - 概率论,扩展中国剩余定理

    有一个猜奖者和一个主持人,一共有 \(n\) 扇门,只有一扇门后面有奖,主持人事先知道哪扇门后有奖,而猜奖者不知道.每一轮,猜奖者选择它认为的有奖概率最大(如果有多个最大,随机选一个)的一扇门,主持人 ...

  2. Wannafly Camp 2020 Day 3F 社团管理 - 决策单调性dp,整体二分

    有 \(n\) 个数构成的序列 \({a_i}\),要将它划分为 \(k\) 段,定义每一段的权值为这段中 \((i,j) \ s.t. \ i<j,\ a_i=a_j\) 的个数,求一种划分方 ...

  3. Wannafly Camp 2020 Day 3D 求和 - 莫比乌斯反演,整除分块,STL,杜教筛

    杜教筛求 \(\phi(n)\), \[ S(n)=n(n+1)/2-\sum_{d=2}^n S(\frac{n}{d}) \] 答案为 \[ \sum_{d=1}^n \phi(d) h(\fra ...

  4. Wannafly Camp 2020 Day 2B 萨博的方程式 - 数位dp

    给定 \(n\) 个数 \(m_i\),求 \((x_1,x_2,...,x_n)\) 的个数,使得 \(x_1 \ xor\ x_2\ xor\ ...\ xor\ x_n = k\),且 \(0 ...

  5. Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元

    给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...

  6. Wannafly Camp 2020 Day 2I 堡堡的宝藏 - 费用流

    感谢这道题告诉我KM求的是 完备 最大权匹配 :( #include <bits/stdc++.h> using namespace std; #define reset(x) memse ...

  7. Wannafly Camp 2020 Day 2J 邦邦的2-SAT模板

    #include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; cout<<n& ...

  8. Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝 - 树链剖分

    如果暴力维护,每次询问时需要对所有孩子做计算 考虑通过树剖来平衡修改与询问的时间,询问时计算重链和父树,轻链的贡献预先维护好,修改时则需要修改可能影响的轻链贡献,因为某个点到根的路径上轻重交替只有 \ ...

  9. Wannafly Camp 2020 Day 2K 破忒头的匿名信 - AC自动机,dp

    给定字典和文章,每个单词有价值,求写文章的最小价值 标准的 AC 自动机 dp,设 \(f[i]\) 表示写 \(s[1..i]\) 的最小价值,建立AC自动机后根据 trans 边暴力转移即可 建了 ...

随机推荐

  1. Python3(八) 枚举详解

    一.枚举其实是一个类 建议标识名字用大写 1.枚举类: from enum import Enum class VIP(Enum):     YELLOW = 1     GREEN = 2      ...

  2. NodeJS 介绍安装

    1.NodeJS简介 Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快速的.可扩展的网络应用.N ...

  3. 怎么用wait、notify巧妙的设计一个Future模式?

    我们知道多线程可以实现同时执行多个任务(只是看起来是同时,其实是CPU的时间片切换特别快我们没感觉而已). 现在假设一个做饭的场景,你没有厨具也没有食材.你可以去网上买一个厨具,但是这段时间,你不需要 ...

  4. BP神经网络拟合给定函数

    近期在准备美赛,因为比赛需要故重新安装了matlab,在里面想尝试一下神将网络工具箱.就找了一个看起来还挺赏心悦目的函数例子练练手: y=1+sin(1+pi*x/4) 针对这个函数,我们首先画出其在 ...

  5. 用c语言实现简单的五子棋

    用c语言实现简单的五子棋 这个小游戏是从零开始的实现的,框架灵感来自于小游戏<走迷宫>. 游戏代码配置: 二维数组+简单逻辑+getch读取键盘+windows函数(刷屏,改颜色,改窗口大 ...

  6. mysql中EXPLAIN 的作用

    (一)id列: (1).id 相同执行顺序由上到下 mysql> explain -> SELECT*FROM tb_order tb1 -> LEFT JOIN tb_produc ...

  7. warning Unexpected use of undefined no-undefined

    报错翻译:警告意外使用未定义的no-undefined(谷歌这次翻译的不行) 报错原因undefined直接使用了,如下↓ 其实报错的意思就是这样不安全,看下面一个例子 var foo = undef ...

  8. Mac下搭建selenium环境

    1,安装selenium 打开terminal,使用以下命令安装selenium:   pip install -U selenium 2,下载chromedriver,并放在python的安装根目录 ...

  9. 使用JDBC分别利用Statement和PreparedStatement来对MySQL数据库进行简单的增删改查以及SQL注入的原理

    一.MySQL数据库的下载及安装 https://www.mysql.com/ 点击DOWNLOADS,拉到页面底部,找到MySQL Community(GPL)Downloads,点击 选择下图中的 ...

  10. (未完成)【Android】MVP模式初见(一)

    最近在阅读郭霖大神的公众号时,分类中架构引起了我的注意. 虽然是个人开发(水平很菜的那种),但最终都要向企业正式项目开发靠近.因此接下来一段时间,主要学习一下MVP架构.Retrofit以及RxJav ...