http://acm.hdu.edu.cn/showproblem.php?pid=4641

http://acm.hdu.edu.cn/showproblem.php?pid=6194

题意: 开始时给出一个字符串,给出两种操作,一种是在字符串后面添加一个字符,
另一个是查询出现过最少出现K次的字串个数。

分析:

建立后缀自动机,添加一个字符插入即可,对于查询,前面计算过的没必要再算,
直接从当前开始往前面找,已经达到K次的就不管,说明前面已经计算过,现在达到
K次的加进答案。

#include<bits/stdc++.h>
using namespace std;
#define mem(a , b) memset(a , b , sizeof(a))
const int maxn = ;
#define ll long long struct SAM{
int trans[maxn<<][] , slink[maxn<<] , maxlen[maxn<<];
int last , now , root;
ll ans=;
int sum[maxn<<];
void newnode(int v)
{
maxlen[++now]=v;
mem(trans[now],); }
void extend(int c , int k)
{
newnode(maxlen[last] + );
int p = last , np = now;sum[now]=;
// cout<<now<<endl;
while(p && !trans[p][c])
{
trans[p][c] = np;
p = slink[p];
}
if(!p) slink[np] = root;
else
{
int q = trans[p][c];
if(maxlen[p] + != maxlen[q])
{
newnode(maxlen[p] + );
int nq = now;
memcpy(trans[nq] , trans[q] , sizeof(trans[q]));
sum[nq]=sum[q];///分开的节点要继承
slink[nq] = slink[q];
slink[q] = slink[np] = nq;
while(p && trans[p][c] == q)
{
trans[p][c] = nq;
p = slink[p];
}
}
else
{
slink[np]=q;
}
}
last = np;
int w=np;
while(w && sum[w] < k )
{
sum[w]++;
if(sum[w]==k) ans+=maxlen[w]-maxlen[slink[w]];
w=slink[w];
}
// cout<<np<<endl;
}
void init()
{
root = last = now = ;
slink[root]=;
mem(trans[root],);
sum[root]=;
ans=;
} }sam;
int main()
{ int n,q,k;
while(scanf("%d%d%d",&n,&q,&k)!=EOF){
sam.init();
char str[maxn];scanf("%s",str);
for(int i= ; i<n ; i++)
{
sam.extend(str[i]-'a' , k);
}
while(q--)
{
int T;scanf("%d",&T);
getchar(); if(T==)
{ char op;
op=getchar();
sam.extend(op-'a' , k );
// cout<<op<<endl;
}
else
{
printf("%lld\n",sam.ans);
}
}
} }

关于恰好出现k次的字符串 , 我们只要求出至少k次的字串 - 至少(k+1)次的字串 ,不恰好就是k次吗

#include<bits/stdc++.h>
using namespace std;
#define mem(a , b) memset(a , b , sizeof(a))
const int maxn = ;
#define ll long long struct SAM{
int trans[maxn<<][] , slink[maxn<<] , maxlen[maxn<<];
int last , now , root;
ll ans=;
int sum[maxn<<];
void newnode(int v)
{
maxlen[++now]=v;
mem(trans[now],); }
void extend(int c , int k)
{
newnode(maxlen[last] + );
int p = last , np = now;sum[now]=;
// cout<<now<<endl;
while(p && !trans[p][c])
{
trans[p][c] = np;
p = slink[p];
}
if(!p) slink[np] = root;
else
{
int q = trans[p][c];
if(maxlen[p] + != maxlen[q])
{
newnode(maxlen[p] + );
int nq = now;
memcpy(trans[nq] , trans[q] , sizeof(trans[q]));
sum[nq]=sum[q];///分开的节点要继承
slink[nq] = slink[q];
slink[q] = slink[np] = nq;
while(p && trans[p][c] == q)
{
trans[p][c] = nq;
p = slink[p];
}
}
else
{
slink[np]=q;
}
}
last = np;
int w=np;
while(w && sum[w] < k )
{
sum[w]++;
if(sum[w]==k) ans+=maxlen[w]-maxlen[slink[w]];
w=slink[w];
}
// cout<<np<<endl;
}
void init()
{
root = last = now = ;
slink[root]=;
mem(trans[root],);
sum[root]=;
ans=;
} }sam;
int main()
{ int n,q,k;
int t;scanf("%d",&t);
while(t--)
{ string str;int k;
cin>>k>>str;
sam.init();
n=str.size();
for(int i= ; i<n ; i++)
{
sam.extend(str[i]-'a' , k);
}
ll sum1=sam.ans;
sam.init();
for(int i= ; i<n ; i++)
{
sam.extend(str[i]-'a' , k+);
}
ll sum2=sam.ans;
printf("%lld\n",sum1-sum2);
} }

HDU4641 || 6194多校 (后缀自动机-最少出现K次的字串个数 || 恰好出现K次字符串的个数)的更多相关文章

  1. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  2. CodeForces-427D:Match & Catch (后缀自动机)

    Police headquarter is monitoring signal on different frequency levels. They have got two suspiciousl ...

  3. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  4. 【算法】后缀自动机(SAM) 初探

    [自动机] 有限状态自动机的功能是识别字符串,自动机A能识别字符串S,就记为$A(S)$=true,否则$A(S)$=false. 自动机由$alpha$(字符集),$state$(状态集合),$in ...

  5. 一文读懂后缀自动机 Suffix_Automata

    原论文(俄文)地址:suffix_automata 原翻译(中文)地址:后缀自动机详解(DZYO的博客) Upd:强推浅显易懂(?)的SAM讲解 后缀自动机 后缀自动机(单词的有向无环图)--是一种强 ...

  6. 『后缀自动机入门 SuffixAutomaton』

    本文的图片材料多数来自\(\mathrm{hihocoder}\)中详尽的\(SAM\)介绍,文字总结为原创内容. 确定性有限状态自动机 DFA 首先我们要定义确定性有限状态自动机\(\mathrm{ ...

  7. Codechef2015 May - Chef and Strings (后缀自动机)

    用后缀自动机统计出出现1~n次的串的数量f[i] 对于ans[k]=sigma(f[i]*C(i,k)) i>=k ; mo=; ..maxn] of dword; nt:..maxn,'a'. ...

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

    Problem Description Given a string S. K-string is the sub-string of S and it appear in the S at leas ...

  9. spoj 1812 lcsII (后缀自动机)

    spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ...

随机推荐

  1. 基于swoole搭建聊天室程序

    1. 创建websocket服务器 swoole从1.7.9版本开始, 内置了websocket服务器功能,我们只需几行简单的PHP代码,就可以创建出一个异步非阻塞多进程的WebSocket服务器. ...

  2. linux每天一小步---mkdir命令详解

    1 命令功能 mkdir命令用于创建单个目录或者多级目录,但前提在于用户对于当前目录有写权限. 2 命令语法 mkdir  [选项]  [目录名] 3 命令参数 -m 在创建目录的同时设定目录权限(而 ...

  3. 用shell脚本 计算两个数的加减乘除取余

    #! /bin/bash # read -p '请输入数:' a //输入 read -p '请输入数:' b echo '$a+$b=' $(( a + b )) //输出 echo '$a-$b= ...

  4. Oracle Key Flexfields Qualifiers

    Oracle Key Flexfields Qualifiers 1.     Application Developer è Flexfield è Key è Register Title: Ac ...

  5. Android Camera的使用(一) 读书笔记

    原文地址 https://blog.csdn.net/junzia/article/details/52301199 拍照步骤1.添加权限2.开启相机时check一下是否有摄像头3.对预览大小.照片大 ...

  6. cocos2dx常见Action(转)

    本文转载自:http://blog.csdn.net/ff313976/article/details/23667209 bool HelloWorld::init(){ ////////////// ...

  7. IIS部署网站常见问题

    有时候Web项目在VS开发环境下没有问题,但是在IIS服务器下却出现了问题. 这让人很抓狂. 在这里总结下通常发生这种问题的几个主要原因. 1.IIS注册.Net框架. 1.1:C:\WINDOWS\ ...

  8. 自定义Team Foundation Server (TFS) 与Project Professional的集成字段

    用户可以象使用Office Excel一样,使用Project Professional连接TFS,将数据下载到本地修改,并且发布到TFS服务器上,如果你习惯使用Project来计划你的项目,那么Pr ...

  9. asp.net core部署到iis

    asp.net core项目部署到IIS稍微不同于之前,记录几个要点: 一.下载安装.NET Core 托管捆绑包,下载地址,这个链接或许不是最新的了,官方文档里面有这个链接,到下图所示位置即可找到. ...

  10. AI-Info-Micron:人如其食:人工智能和人类微生物组

    ylbtech-AI-Info-Micron:人如其食:人工智能和人类微生物组 1.返回顶部 1. 人如其食:人工智能和人类微生物组 “相信你身体发出的信号”,的确是一个很好的建议.研究人员在不遗余力 ...