K-string

\[Time Limit: 2000 ms\quad Memory Limit: 131072 kB
\]

题意

给出长度为 \(n\) 的字符串,接下来跟着 \(m\) 次操作,每次 \(1\) 操作往字符串末尾加一个 \(char\),\(2\) 操作统计字符串中出现次数 \(\geq K\) 的字符串个数。

思路

统计一个字符串出现个数,可以用 \(dp[father] = \sum dp[u]\),来计算,那么我们可以知道,一个点从本身往根跑的过程,这个 \(dp\) 值是一直在增大的,所以只要跑到某一个地方的 \(dp \geq K\),就可以不往上更新了,这样插入一个字符,更新一次,边更新边统计答案就可以了。(数据比较水,这样暴力在全是 \(a\) 的情况下是会 \(T\) 的)

这题我用结构体数组写 \(sam\) 被卡了,最后换了纯数组的 \(sam\)。\(emmm\)

/***************************************************************
> File Name : a.cpp
> Author : Jiaaaaaaaqi
> Created Time : 2019年06月06日 星期四 00时14分49秒
***************************************************************/ #include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int> typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 5e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T; struct Sam {
int node[maxn][27], fa[maxn], step[maxn];
int dp[maxn];
int sz, last, K, ans;
int newnode() {
mes(node[++sz], 0);
fa[sz] = step[sz] = 0;
dp[sz] = 0;
return sz;
}
void init() {
ans = sz = 0;
last = newnode();
}
void insert(int k) {
int p = last, np = last = newnode();
step[np] = step[p]+1;
for(; p&&!node[p][k]; p=fa[p])
node[p][k] = np;
if(p==0) {
fa[np] = 1;
} else {
int q = node[p][k];
if(step[q] == step[p]+1) {
fa[np] = q;
} else {
int nq = ++sz;
memcpy(node[nq], node[q], sizeof(node[q]));
dp[nq] = dp[q];
fa[nq] = fa[q];
step[nq] = step[p]+1;
fa[np] = fa[q] = nq;
for(; p&&node[p][k]==q; p=fa[p])
node[p][k] = nq;
}
}
}
void update(int p) {
for(; p&&dp[p]<K; p=fa[p]) {
dp[p]++;
if(dp[p]>=K) ans+=step[p]-step[fa[p]];
}
}
} sam;
char s[50005]; int main() {
while(~scanf("%d%d%d", &n, &m, &sam.K)) {
scanf("%s", s+1);
sam.init();
int len = strlen(s+1);
for(int i=1; i<=len; i++) {
sam.insert(s[i]-'a'+1);
sam.update(sam.last);
}
char ss[5];
while(m--) {
int id;
scanf("%d", &id);
if(id == 1) {
scanf("%s", ss+1);
sam.insert(ss[1]-'a'+1);
sam.update(sam.last);
} else {
printf("%d\n", sam.ans);
}
}
}
return 0;
}

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

  1. HDU 4436 (后缀自动机)

    HDU 4436 str2int Problem : 给若干个数字串,询问这些串的所有本质不同的子串转换成数字之后的和. Solution : 首先将所有串丢进一个后缀自动机.由于这道题询问的是不同的 ...

  2. HDU 4622 (后缀自动机)

    HDU 4622 Reincarnation Problem : 给一个串S(n <= 2000), 有Q个询问(q <= 10000),每次询问一个区间内本质不同的串的个数. Solut ...

  3. HDU 4416 (后缀自动机)

    HDU 4416 Good Article Good sentence Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现. Solution :首先对所有的T串建立后缀自 ...

  4. Alice's Classified Message HDU - 5558 后缀自动机求某个后缀出现的最早位置

    题意: 给定一个长度不超过 10W 的只包含小写字母的字符串,从下标 0 到 n−1.从下标 0 开始操作, 每次对于下标 pos查找下标 pos 开始的子串中最长的在其他地方出现过的长度,其他出现的 ...

  5. str2int HDU - 4436 后缀自动机求子串信息

    题意: 给出 n 个串,求出这 n 个串所有子串代表的数字的和. 题解; 首先可以把这些串构建后缀自动机(sam.last=1就好了), 因为后缀自动机上从 root走到的任意节点都是一个子串,所有可 ...

  6. 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)

    题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...

  7. hdu 6208(后缀自动机、或者AC自动机

    题意:给你n个字符串,问你是否存在一个字符串可以从中找到其他n-1个字符串. 思路:其实很简单,找到最长的那个字符串对他进行匹配,看是否能匹配到n-1个字符串. 可以用AC自动机或者后缀自动机做,但是 ...

  8. HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)

    http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样 ...

  9. Boring counting HDU - 3518 后缀自动机

    题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...

  10. HDU 5442 后缀自动机+kmp

    题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样大,希望找到起始位置最小的,如果还相同,就默认顺时针 比赛一直因为处理最小位置出错,一结束就想 ...

随机推荐

  1. 贪心 + 计算几何 --- Radar Installation

    Radar Installation Description Assume the coasting is an infinite straight line. Land is in one side ...

  2. ORA-01779: 无法修改与非键值保存表对应的列

    项目中通过子查询更新数据时遇到ORA-01779: 无法修改与非键值保存表对应的列,模拟过程如下: 1.创建测试表 CREATE TABLE tt1 (ID INT,col1 VARCHAR2()); ...

  3. Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

    Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只 ...

  4. /etc/skel目录

    /etc/skel目录 Linux中的/etc/skel目录(skel是skeleton的缩写,意为骨骼.框架.)是用来存放新用户配置文件的目录,当我们添加新用户时,这个目录下的所有文件会自动被复制到 ...

  5. 设计模式之(六)原型模式(ProtoType)

    认识原型模式 原型模式是比较简单的设计模式.废话不多说,直接看定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.通过实例指定种类,种类就是初始化的类,然后通过拷贝创建对象.先展示一个 ...

  6. SpringCloud高并发性能优化

    1. SpringCloud高并发性能优化 1.1. 前言 当系统的用户量上来,每秒QPS上千后,可能就会导致系统的各种卡顿,超时等情况,这时优化操作不可避免 1.2. 优化步骤 第一步:优化大SQL ...

  7. spring boot 的request.getServletContext().getRealPath路径获取问题

    默认情况下springboot中request.getServletContext().getRealPath 返回的是一个临时文件夹的地址 通过查看源代码 位置在 org.springframewo ...

  8. Unity编辑器扩展中,使用Unity自带的GUIStyle

    在进行编辑器扩展时,创建组件的方法一般都会提供GUIStyle参数,可以让我们自定义样式.修改背景图,字体大小,颜色等等. 比如,创建Button组件的方法:public static bool Bu ...

  9. java String字符串编码类型转换

    /** * 前后端数据乱码问题 * 解决办法1: * 乱码原因:一编一解码型不一致导致. * [main description] * @param {[type]} String[] args [d ...

  10. workman即时推送

    https://www.workerman.net/web-sender 下载源码解压后运行  start_for_win.bat  如果提示不成功,就把php路径配置到环境变量中去即可 运行后打开浏 ...