题意:给你一个字符串和一个正整数K,让你输出恰好出现K次的子串的数量。

对后缀链接树进行dp预处理后,SAM每个点的endpos大小就是该点结尾的子串出现的次数,maxlen-minlen+1就是子串的数量,所以直接对endpos大小为K的点的(maxlen-minlen+1)求和即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXL 100000
#define MAXC 26
int v[2*MAXL+10],__next[2*MAXL+10],first[2*MAXL+10],e;
void AddEdge(int U,int V){
v[++e]=V;
__next[e]=first[U];
first[U]=e;
}
char s[MAXL+10];
int len;
struct SAM{
int endcnt[2*MAXL+10];
int n,maxlen[2*MAXL+10],minlen[2*MAXL+10],trans[2*MAXL+10][MAXC],slink[2*MAXL+10];
void clear(){
for(int i=0;i<=n;++i){
endcnt[i]=maxlen[i]=minlen[i]=slink[i]=first[i]=0;
memset(trans[i],0,sizeof(trans[i]));
}
n=e=0;
}
int new_state(int _maxlen,int _minlen,int _trans[],int _slink){
maxlen[n]=_maxlen;
minlen[n]=_minlen;
for(int i=0;i<MAXC;++i){
if(_trans==NULL){
trans[n][i]=-1;
}
else{
trans[n][i]=_trans[i];
}
}
slink[n]=_slink;
return n++;
}
int add_char(char ch,int u){
if(u==-1){
return new_state(0,0,NULL,-1);
}
int c=ch-'a';
int z=new_state(maxlen[u]+1,-1,NULL,-1);
endcnt[z]=1;
int v=u;
while(v!=-1 && trans[v][c]==-1){
trans[v][c]=z;
v=slink[v];
}
if(v==-1){
minlen[z]=1;
slink[z]=0;
return z;
}
int x=trans[v][c];
if(maxlen[v]+1==maxlen[x]){
minlen[z]=maxlen[x]+1;
slink[z]=x;
return z;
}
int y=new_state(maxlen[v]+1,-1,trans[x],slink[x]);
slink[y]=slink[x];
minlen[x]=maxlen[y]+1;
slink[x]=y;
minlen[z]=maxlen[y]+1;
slink[z]=y;
int w=v;
while(w!=-1 && trans[w][c]==x){
trans[w][c]=y;
w=slink[w];
}
minlen[y]=maxlen[slink[y]]+1;
return z;
}
void dfs(int U){
for(int i=first[U];i;i=__next[i]){
dfs(v[i]);
endcnt[U]+=endcnt[v[i]];
}
}
void work_slink_tree(){
for(int i=1;i<n;++i){
AddEdge(slink[i],i);
}
dfs(0);
}
}sam;
int anss[MAXL+10];
int T,K;
typedef long long ll;
int main(){
// freopen("a.in","r",stdin);
scanf("%d",&T);
for(;T;--T){
scanf("%d%s",&K,s);
len=strlen(s);
int U=sam.add_char(0,-1);
for(int i=0;i<len;++i){
U=sam.add_char(s[i],U);
}
sam.work_slink_tree();
ll ans=0;
for(int i=1;i<sam.n;++i){
if(sam.endcnt[i]==K){
ans+=(ll)(sam.maxlen[i]-sam.minlen[i]+1);
}
}
printf("%d\n",ans);
sam.clear();
}
return 0;
}

【后缀自动机】hdu6194 string string string的更多相关文章

  1. 【Hihocoder1413】Rikka with String(后缀自动机)

    [Hihocoder1413]Rikka with String(后缀自动机) 题面 Hihocoder 给定一个小写字母串,回答分别把每个位置上的字符替换为'#'后的本质不同的子串数. 题解 首先横 ...

  2. 【计蒜客】是男人就过 8 题--Pony.AI 题 A. A String Game 后缀自动机+SG函数

    [题目]A. A String Game [题意]给定目标串S和n个子串Ti,Alice和Bob轮流选择一个子串操作,必须且只能在子串末尾添加一个字符使得新串也是S的子串,不能操作即输,求胜利者.|S ...

  3. 2020牛客暑期多校训练营(第四场) C - Count New String (字符串,广义后缀自动机,序列自动机)

    Count New String 题意: 定义字符串函数 \(f(S,x,y)(1\le x\le y\le n)\),返回一个长度为y-x+1的字符串,第 i 位是 \(max_{i=x...x+k ...

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

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

  5. BZOJ5408: string(广义后缀自动机,LCT)

    传送门 解题思路: 首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内. 那么考虑一个新的点在串中对串答案的贡献在一条树链 ...

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

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

  7. <string> 与<string.h>、<cstring>的区别

    <string.h> <string.h>是C版本的头文件,包含比如strcpy.strcat之类的字符串处理函数. <cstring> 在C++标准化(1998年 ...

  8. 再探Java基础——String.format(String format, Object… args)的使用

    最近看到类似这样的一些代码:String.format("参数%s不能为空", "birthday"); 以前还没用过这功能不知咐意思,后研究了一下,详细讲解如 ...

  9. C/C++ - <string> 与<string.h>、<cstring>的区别

    <string.h><string.h>是C版本的头文件,包含比如strcpy.strcat之类的字符串处理函数. <string><string>是C ...

  10. File(File f, String child) File(String parent, String child)

    (转载)File(File f, String child) 根据f 抽象路径名和 child 路径名字符串创建一个新 File 实例. f抽象路径名用于表示目录,child 路径名字符串用于表示目录 ...

随机推荐

  1. js jq插件 显示中文时间戳 刚刚 N分钟前 N小时前 今天 上午 下午 日期格式化

    注:页面需提前引用JQ ; $.fn.extend({ /* ** notes: 获取13位时间戳的简单操作 ** new Date('2018-02-01 15:10:00').getTime() ...

  2. Spring Boot中配置文件application.properties使用

    一.配置文档配置项的调用 启动后在浏览器直接输入http://localhost:18080/user/test,就直接打印出配置文件中的配置内容. 二.绑定对象bean调用 有时候属性太多了,一个个 ...

  3. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  4. java解析XML之DOM解析和SAX解析(包含CDATA的问题)

    Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档: SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档:SAX采用事件驱动的方式解析XML.如同在电 ...

  5. Perl6 Bailador框架(3):路径匹配

    use v6; use Bailador; =begin pod 注意的是, 当/:one设置时 虽然你有/admin或/about, 但这个/:one不会跟现有的匹配 只跟没有的匹配: 也就是说, ...

  6. io多路复用-select()

    参照<Unix网络编程>相关章节内容,实现了一个简单的单线程IO多路复用服务器与客户端. 普通迭代服务器,由于执行recvfrom则会发生阻塞,直到客户端发送数据并正确接收后才能够返回,一 ...

  7. MD5加密学习

    MD5(Message Digest --消息摘要算法)算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法(易错),任何长度的任意内容都可以用MD5计算出散列值.主要作用是[验明“ ...

  8. git清除用户名密码

    问题: remote: HTTP Basic: Access deniedfatal: Authentication failed for 'http://******** 解决方案: git con ...

  9. FTP webReq.ContentType异常的处理

    FtpWebRequest webReq; webReq = (FtpWebRequest)FtpWebRequest.Create(new Uri(updateFileUrl)); FtpWebRe ...

  10. Leetcode 之Add Binary(29)

    比较简单,细节:先将字符串翻转,注意进位. string addBinary(string a, string b) { string result; int len = a.size() > ...