动态维护任意两个后缀的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. 为什么Linux 实例执行 df 和 du 查看磁盘时结果不一致

    问题现象 执行 df -h 查看 ECS Linux 实例文件系统使用率,可以看到 /dev/xvdb1 磁盘占用了约27G,挂载目录为 /opt . 进入到 /opt 目录执行 du -sh ,显示 ...

  2. Hello Rust!

    准备工作 Rust是系统编程语言,会经过传统的编译.链接.生成可执行文件等过程.它依赖c/cpp的编译环境,需要提前安装c/cpp开发环境,比如安装gcc及其依赖等. 安装(macOS / Linux ...

  3. axios中get请求的params参数中带数组的处理方法

    axios中get请求的params参数中带数组时导致向后台传参失败报错:from origin 'http://localhost:8080' has been blocked by CORS po ...

  4. Git push时不需要总输入密码

    遇到问题: 最近因为换了自己的邮箱密码后,每次push的时候都需要填写密码,账号.很烦 解决方法: [戎马半生的答案] (http://www.cnblogs.com/zhaoyu1995/p/650 ...

  5. AMD R2600+微星B450迫击炮配置的新工作机,分享给大家

    上个月,突然觉得自己总做用的电脑有点老了,虽然很不舍陪自己战斗了3,4年的老战士,下了很大的决心,才决定搞一台新的吧,虽然新电脑的配置也不算非常高,但是用于开发的话,也算不错的选择了,特此分享一下.又 ...

  6. C#设计模式学习笔记:(16)观察者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7928521.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第四个模式--观 ...

  7. Linux下使用Nginx

    模拟tomcat集群 1.下载tomcat7,/usr/local下新建目录tomcat,将tomcat7剪切到/usr/local/tomcat wget http://mirror.bit.edu ...

  8. Oracle的overlaps函数转换其他数据库语法

    首先,来介绍一下Oracle的overlaps函数的用法: overlaps函数是用来判断两个时间段是否有重叠的 比如说计算 (a,b),(c,d) 就可以写成: select * from dual ...

  9. html网页基本概念

    什么是网页?html文档经过浏览器内核渲染后展示出来的页面(五大主流浏览器及四大内核) html文档文件名后缀是.html,之前存在的.htm是为支持DOM系统(目前织梦还是用.htm文件名结尾文件) ...

  10. 吴裕雄--天生自然 R语言数据可视化绘图(4)

    par(ask=TRUE) # Basic scatterplot library(ggplot2) ggplot(data=mtcars, aes(x=wt, y=mpg)) + geom_poin ...