Problem Description
Given a string S. K-string is the sub-string of S and it appear in the S at least K times.It means there are at least K different pairs (i,j) so that Si,Si+1... Sj equal to this K-string. Given m operator or query:1.add a letter to the end of S; 2.query how many different K-string currently.For each query ,count the number of different K-string currently.
 
Input
The input consists of multiple test cases. Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S. The second line consists string S,which only contains lowercase letters. The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
 
Output
For each query print an integer — the number of different K-string currently.
 
Sample Input
3 5 2
abc
2
1 a
2
1 a
2
 
Sample Output
0
1
1
 
题意: 开始时给出一个字符串,给出两种操作,一种是在字符串后面添加一个字符,
另一个是查询出现过K次的字串个数。
解析: 建立后缀自动机,添加一个字符插入即可,对于查询,前面计算过的没必要再算,
直接从当前开始往前面找,已经达到K次的就不管,说明前面已经计算过,现在达到
K次的加进答案。
 
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=;
int N,M,K;
struct SAM
{
int ch[maxn][];
int pre[maxn],step[maxn];
int last,id,ans;
int num[maxn];
void init()
{
ans=last=id=;
memset(ch[],-,sizeof(ch[]));
pre[]=-; step[]=;
}
void Insert(int c)
{
int p=last,np=++id;
step[np]=step[p]+;
memset(ch[np],-,sizeof(ch[np])); num[np]=; while(p!=-&&ch[p][c]==-) ch[p][c]=np,p=pre[p];
if(p==-) pre[np]=;
else
{
int q=ch[p][c];
if(step[q]!=step[p]+)
{
int nq=++id;
memcpy(ch[nq],ch[q],sizeof(ch[q])); num[nq]=num[q];
step[nq]=step[p]+;
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
while(p!=-&&ch[p][c]==q) ch[p][c]=nq,p=pre[p];
}
else pre[np]=q;
}
last=np; while(np!=-&&num[np]<K) //没有达到K次的就加1
{
num[np]++;
if(num[np]>=K) ans+=step[np]-step[pre[np]]; //加上答案
np=pre[np];
}
}
}sam;
char S[];
int main()
{
while(scanf("%d%d%d",&N,&M,&K)!=EOF)
{
scanf("%s",S);
sam.init();
for(int i=;i<N;i++) sam.Insert(S[i]-'a');
int type;
char c;
while(M--)
{
scanf("%d",&type);
if(type==){ scanf(" %c",&c); sam.Insert(c-'a'); }
else printf("%d\n",sam.ans);
}
}
return ;
}

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

  1. 2018.12.15 hdu4641 K-string(后缀自动机)

    传送门 后缀自动机基础题. 题意简述:支持动态在串尾插入字符,查询在串中出现超过kkk次的子串的个数. 动态修改samsamsam,每次增量构造好了之后在parentparentparent树上从新建 ...

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

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

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

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

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

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

  5. HDU4641 K-string(后缀自动机+线段树合并)

    先考虑没有动态加字符怎么做.计算每个节点的贡献,当|right|>=k时将len-lenfa计入即可. 动态加字符后,这个东西难以用LCT维护.于是考虑离线.建完SAM后,容易发现每个节点在时间 ...

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

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

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

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

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

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

  9. bzoj 5408: string 后缀自动机 + LCT

    联赛前练练码力. code: #include <vector> #include <cstdio> #include <cstring> #include < ...

  10. HDU4641 || 6194多校 (后缀自动机-最少出现K次的字串个数 || 恰好出现K次字符串的个数)

    http://acm.hdu.edu.cn/showproblem.php?pid=4641 http://acm.hdu.edu.cn/showproblem.php?pid=6194 题意: 开始 ...

随机推荐

  1. (转)keytools命令

    结合网络资源,对keytool使用总结,以备后用: Keytool是一个Java数据证书的管理工具 ,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件 ...

  2. 美丽的for循环语句

    美丽的for循环语句 题目:用for循环语句实现四个三角形不同的形状.   图案:    ---------------第一个三角形图形形状----------------**********第二个三 ...

  3. 从 Windows 到 Android: 威胁的持续迁移

    作者:趋势科技 新闻媒体现在正喧腾着 OBAD 这个 Android 恶意软件,这也是到目前为止,Android 恶意软件中“最坏”,同时也是“最先进的 Android 木马程序”.除了各种强大的功能 ...

  4. VS2008编程软件过期的问题,过期弹出须要升级窗体的解决的方法

    找到安装文件,再点autorun.exe安装文件,然后反复安装过程就会弹出须要填写系列号的地方,天上以下第一个系列号就可以. Visual Studio 2008 Professional Editi ...

  5. 将apk文件添加到Android模拟器(AVD)中运行

    apk不同exe和jar文件,apk需要在安卓系统中运行,单有一个apk文件还是没用,不能直接拖进AVD中(当然可以直接放到安卓系统的手机中) 由于我们的eclipse大都是已经安装好,解压直接使用的 ...

  6. Keil IDE指南.

    Keil IDE指南(转载) 熟悉Keil C 51的朋友对于Keil MDK上手应该比较容易,毕竟界面是很像的.但ARM内核毕竟不同于51内核,因此无论在设置上还是在编程思想上,都需要下番功夫研究的 ...

  7. jstl经典用法

    jstl的forEach使用和set变量实现自增: <body> <c:set var="index" value="0" /> < ...

  8. jQuery选择器 之详述

    jQuery选择器 一. 单词小计 Pervious 上一页sibling  同级first  第一last  最后not  不 Even  偶数    odd  奇数 header  页眉 一.jQ ...

  9. 初学Java ssh之Spring 第三篇

    在这篇中,我学习了依赖注入的两种方式:设值注入和构造注入. 在我们以前的思维中,如果调用一个类时,我们都需要将其手动实例化,当我们创建被调用的工作不需要我们完成时,这就是控制反转,当这个将被调用的实例 ...

  10. cas+tomcat+shiro实现单点登录-1-tomcat添加https协议

    目录 1.tomcat添加https安全协议 2.下载cas server端部署到tomcat上 3.CAS服务器深入配置(连接MYSQL) 4.Apache Shiro 集成Cas作为cas cli ...