HDU4641 || 6194多校 (后缀自动机-最少出现K次的字串个数 || 恰好出现K次字符串的个数)
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次字符串的个数)的更多相关文章
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- CodeForces-427D:Match & Catch (后缀自动机)
Police headquarter is monitoring signal on different frequency levels. They have got two suspiciousl ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- 【算法】后缀自动机(SAM) 初探
[自动机] 有限状态自动机的功能是识别字符串,自动机A能识别字符串S,就记为$A(S)$=true,否则$A(S)$=false. 自动机由$alpha$(字符集),$state$(状态集合),$in ...
- 一文读懂后缀自动机 Suffix_Automata
原论文(俄文)地址:suffix_automata 原翻译(中文)地址:后缀自动机详解(DZYO的博客) Upd:强推浅显易懂(?)的SAM讲解 后缀自动机 后缀自动机(单词的有向无环图)--是一种强 ...
- 『后缀自动机入门 SuffixAutomaton』
本文的图片材料多数来自\(\mathrm{hihocoder}\)中详尽的\(SAM\)介绍,文字总结为原创内容. 确定性有限状态自动机 DFA 首先我们要定义确定性有限状态自动机\(\mathrm{ ...
- 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'. ...
- 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 ...
- spoj 1812 lcsII (后缀自动机)
spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ...
随机推荐
- zTree的简单使用
理论可以看:http://www.cnblogs.com/shinhwazt/p/5828031.html zTree包:链接:http://pan.baidu.com/s/1eR4xP6M 密码:w ...
- context:propertyPlaceholder
Activates replacement of ${...} placeholders by registering a PropertySourcesPlaceholderConfigurer w ...
- Haodoop RPC解析
1. 前言 1 2. Hadoop RPC 1 2.1. 总体结构 1 2.1.1. RPC Interface 1 2.1.2. RPC Server 1 2.1.3. RPC Client 1 2 ...
- canvas里调用getImageData的报security的问题
canvas元素支持绘制任意图片元素: var ctx = document.getElementById("canvas").getContext("2d") ...
- scala中Nil用法
http://www.runoob.com/scala/scala-lists.html 即Nil是空List 双冒号是追加进入 package com.yjsj.spark object scala ...
- iOS9 Https技术预研
一.服务器需要做的事情: 1.要注意 App Transport Security 要求 TLS 1.2, 2.而且它要求站点使用支持forward secrecy协议的密码. 3.证书也要求是符合A ...
- Objective-C 学习笔记(五) 指针
Objective-C 指针 每一个变量是一个内存位置和每一个存储单元都有其定义的地址,可以使用符号(&)的运算符,它表示内存中的地址访问. a. 我们定义一个指针变量 b. 分配一个指针变量 ...
- 如何搭建eclipse+maven环境
Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包.本文仅对Eclipse中如何安装.配置和使用Maven进行了介绍.完全step by step. 如果觉得本文 ...
- 使用Eclipse切换TFS工作区
这个问题首先牵涉到两个概念: - Eclipse的工作区:Eclipse的工作区是运行Eclipse时需要连接的本地代码空间,默认情况下,在Eclipse中创建的项目都保存在Eclipse的工作区中 ...
- 常用脚本--SQL Server获取OS日志
--=================================================== --SQL Server获取OS日志: ), ), ), ) select @start_d ...