原题链接

题意

  • 每个测试点,一开始给我们n,m,k然后是一个长度为n的字符串。

  • 之后m次操作,1 c是往字符串后面添加一个字符c,2是查询字符串中出现k次以及以上的子串个数,m为2e5

思路

  • 首先可以看出这是在线算法(离线其实也可以),然后是查询出现至少k次的子串,这样我们可以直接联系到后缀自动机,与我们本题的需求较为契合

  • 我们知道后缀自动机中,每个节点代表的不同子串数量为

\[cnt_v = len(v) - len(link(v))
\]
  • 而每个节点的出现次数是其本身与link树的所有子树的标记次数之和,所以每次插入一个字符之后,我们都沿着link向上更新,对沿路节点的标记+1,如果出现了加完后标记正好为k的节点,则
\[ans += len(v) - len(link(v)
\]

然后如果某个节点在访问之前就达到了k,则不需要继续向上更新了,因为上面的节点也肯定大于等于k,并且在之前就被记录了

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = 250000; int n, m, k, last = 0, co = 0;
long long ans = 0;
char ss[N + 5]; struct Sam
{
int fl;
int len;
int fail;
int sn[26];
} sam[N * 2 + 5]; void inits(int o)
{
sam[o].fail = -1;
sam[o].len = 0;
sam[o].fl = 0;
for (int i = 0; i < 26; ++i)
{
sam[o].sn[i] = 0;
}
} void update(int o)
{
while (o > 0 && sam[o].fl < k)
{
++sam[o].fl;
if (sam[o].fl >= k)
{
ans += sam[o].len - sam[sam[o].fail].len;
}
o = sam[o].fail;
}
} void add(char c)
{
int noww = ++co;
inits(noww);
sam[noww].len = sam[last].len + 1;
int p = last;
while (p != -1 && !sam[p].sn[c - 'a'])
{
sam[p].sn[c - 'a'] = noww;
p = sam[p].fail;
}
if (p == -1)
{
sam[noww].fail = 0;
}
else
{
int q = sam[p].sn[c - 'a'];
if (sam[q].len == sam[p].len + 1)
{
sam[noww].fail = q;
}
else
{
int cp = ++co;
sam[cp] = sam[q];
sam[cp].len = sam[p].len + 1;
// sam[cp].fl = 0; sam[q].fail = cp;
sam[noww].fail = cp;
while (p != -1 && sam[p].sn[c - 'a'] == q)
{
sam[p].sn[c - 'a'] = cp;
p = sam[p].fail;
}
}
}
last = noww;
update(noww);
} int main()
{
while (scanf("%d%d%d", &n, &m, &k) == 3)
{
co = 0;
last = 0;
scanf("%s", ss);
ans = 0;
inits(0);
for (int i = 0; ss[i]; ++i)
{
add(ss[i]);
}
for (int i = 1; i <= m; ++i)
{
int opt;
scanf("%d", &opt);
if (opt == 1)
{
char c[5];
scanf("%s", c);
add(c[0]);
}
else
{
printf("%lld\n", ans);
}
}
}
return 0;
}

HDU 4641 K string 后缀自动机的更多相关文章

  1. HDU 4622 Reincarnation(后缀自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4622 [题目大意] 给出一个长度不超过2000的字符串,有不超过10000个询问,问[L,R]子串 ...

  2. HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)

    Problem Description In this problem, you are given several strings that contain only digits from '0' ...

  3. 【hihocoder#1413】Rikka with String 后缀自动机 + 差分

    搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...

  4. 牛客多校第四场 I string 后缀自动机/回文自动机

    这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...

  5. HDU 4436 str2int(后缀自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4436 [题目大意] 给出一些字符串,由0~9组成,求出所有不同子串的和. [题解] 将所有字符串添 ...

  6. HDU 4436 str2int (后缀自动机SAM,多串建立)

    str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  7. 识别子串 (string)——后缀自动机+线段树

    题目 [题目描述] 一般地,对于一个字符串 S,和 S 中第 $ i $ 个字符 x,定义子串 $ T=S(i.j) $ 为一个关于 x 的识别子申,当且仅当: 1.$ i \leq x \leq j ...

  8. Codeforces 917F Substrings in a String - 后缀自动机 - 分块 - bitset - KMP

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一个字母串,要求支持以下操作: 修改一个位置的字母 查询一段区间中,字符串$s$作为子串出现的次数 Solution 1 Bitset 每 ...

  9. cf1121F. Compress String(后缀自动机)

    题意 题目链接 Sol 居然出个SAM板子也是没谁了233 #include<bits/stdc++.h> #define Pair pair<int, int> #defin ...

  10. #1413 : Rikka with String 后缀自动机 + 二级差分

    http://hihocoder.com/problemset/problem/1413?sid=1199641 这题断断续续做了2个多星期吧,一直不会 设总答案为sum,替换后新加的子串数量为x,失 ...

随机推荐

  1. C# 在流行度指数上将超过Java

    2023年10月最新的TIOBE编程语言流行指数表明:C#和Java之间的差距从未如此之小,目前,差异仅为1.2%,如果趋势保持这种状态,C#将在大约2个月内超过Java,TIOBE Software ...

  2. 看完包你搞懂Redis缓存穿透、击穿和雪崩!!!说到做到

    缓存穿透 缓存穿透是指当用户对Redis发出无效或者不存在的数据信息操作时,这条数据在Redis中不存在,Redis就会在MySQL数据库中查询,可时无效的信息在mysql数据库中也不存在,就会造成R ...

  3. 开发现代化的.NetCore控制台程序:(2)创建一个C#项目模板

    前言 上一篇文章(开发一个现代化的.NetCore控制台程序,包含依赖注入/配置/日志等要素)介绍了开发现代化的.NetCore控制台程序的细节,但这还不够,我又创建了一个脚手架模板,并命名为 Flu ...

  4. sizeof结构体数组指针和sizeof数组指针的区别

    请思考一下 以下代码输出的 sizeof 分别是多少? #include <stdio.h> typedef struct { char name[100]; unsigned char ...

  5. 栈与队列应用:逆波兰计算器(逆波兰表达式;后缀表达式)把运算符放到运算量后边 && 中缀表达式转化为后缀表达式

    1 //1.实现对逆波兰输入的表达式进行计算如(2-1)*(2+3)= 5 就输入2 1 - 2 3 + * //先把2 1 压栈 遇到-弹栈 再把2 3压进去 遇到+弹栈 最后遇到*弹栈 2 //2 ...

  6. .NET8:快速集成Rapid.NET三维控件

    .NET8正式版本发布了,AnyCAD Rapid.NET针对.NET8进行了升级和优化.本文以WPF项目为例介绍在.NET8中使用AnyCAD Rapid.NET三维控件. 1 从.NET6升级 若 ...

  7. vue禁止浏览器F5进行刷新和监听浏览器刷新事件

    项目中有个这样的需求: 进入视频播放页后,添加一个标识,为了防止用户一次播放多个视频,当离开该页面后,如果是从当前正在播放的视频页面离开的,则离开播放页时清除标识,如果是不是则不清除,并且禁止用户按F ...

  8. 2021牛客多校第一场 I题(DP)

    题意 给定一个长度为 \(n(n<=5000)\) 的排列,两个人轮流从这个序列中选择一个数,要求当前回合此人选择的数大于任意一个已经被选择的数,并且该数在数组中的位置 \(i\) 与此人上一次 ...

  9. 【译】使用 GitHub Copilot 编写 Git 提交

    在花费数小时修复 bug 或更新特性之后,我们开发人员最不愿意做的事情往往是仔细说明 Git 提交的内容.最新的 Visual Studio 预览版可以帮到您.使用新的生成 Git 提交消息特性来帮助 ...

  10. HoG / SIFT 学习指北

    本文 OI / ACM 无关. Explain HoG 原文出处: N. Dalal, and B. Triggs, Histograms of oriented gradients for huma ...