题目链接

Problem Description
Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle Mao was so lazy that he left the problem to you. I hope you can give him a solution.
Given a string s, we define a substring that happens exactly k times as an important string, and you need to find out how many substrings which are important strings.
 
Input
The first line contains an integer T (T≤100) implying the number of test cases.
For each test case, there are two lines:
the first line contains an integer k (k≥1) which is described above;
the second line contain a string s (length(s)≤105).
It's guaranteed that ∑length(s)≤2∗106.
 
Output
For each test case, print the number of the important substrings in a line.
 
Sample Input
2
2
abcabc
3
abcabcabcabc
 
Sample Output
6
9
 
 
题意:有一个字符串s,求其中恰好出现k次的子串有多少个?
 
思路:后缀数组,通过后缀数组算法可以知道每个后缀的排名,如果有某个子串恰好出现k次,那么必定有k个对应的后缀 即这个子串是这k个后缀串的前缀,那么这k个后缀串的排名一定是连续的,所以我们按排名从1~len(s)依次开始 取连续k个后缀串,可以根据height[]数组快速算出当前这k个后缀串的最大公共前缀长度len,那么长为1到len的前缀子串,这k个串都含有,设当前开始k个串为 i到i+k-1 ,那么如果子串长过短,可能 i-1 或 i+k 这个串也含有相应的子串,所以计算出 i 和 i-1 串,i+k和i+k-1的最大公共前缀长为m,那么之前取的子串长必须大于m才能保证 i-1 和 i+k 不含有相应的子串,只有i~i+k-1这k个串含有相应的子串。
 
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1e5+;
char s[N];
int k;
int wa[N],wb[N],wv[N],wss[N];
int sa[N],ran[N],height[N];
int f[N][]; int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(char *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) wss[i]=;
for(i=; i<n; i++) wss[x[i]=(int)r[i]]++;
for(i=; i<m; i++) wss[i]+=wss[i-];
for(i=n-; i>=; i--) sa[--wss[x[i]]]=i;
for(j=,p=; p<n; j*=,m=p)
{
for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) wss[i]=;
for(i=; i<n; i++) wss[wv[i]]++;
for(i=; i<m; i++) wss[i]+=wss[i-];
for(i=n-; i>=; i--) sa[--wss[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
void callheight(char *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++)
ran[sa[i]]=i;
for(i=;i<n;height[ran[i++]]=k)
for(k?k--:,j=sa[ran[i]-];r[i+k]==r[j+k];k++);
return ;
}
void init(int len)
{
for(int i=;i<=len;i++) f[i][]=height[i];
for(int s=;(<<s)<=len;s++)
{
int tmp=(<<s);
for(int i=;i+tmp-<=len;i++)
{
f[i][s]=min(f[i][s-],f[i+tmp/][s-]);
}
}
}
int cal(int l,int r)
{
int len=log2(r-l+);
int ans=min(f[l][len],f[r-(<<len)+][len]);
return ans;
}
int main()
{
int T; cin>>T;
while(T--)
{
scanf("%d%s",&k,s);
int len=strlen(s);
da(s,sa,len+,);
callheight(s,sa,len);
init(len);
int ans=;
for(int i=;i+k-<=len;i++)
{
int j=i+k-;
int tmp=height[i];
if(j+<=len) tmp=max(tmp,height[j+]);
int x;
if(k!=) { x=cal(i+,j); }
else x=len-sa[i];
ans+=max(,x-tmp);
}
printf("%d\n",ans);
}
return ;
}
 
 

hdu 6194 沈阳网络赛--string string string(后缀数组)的更多相关文章

  1. [2019CCPC网络赛][hdu6704]K-th occurrence(后缀数组&&主席树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6704 题意为查询子串s[l...r]第k次出现的位置. 写完博客后5分钟的更新 写完博客才发现这份代码 ...

  2. hdu 6199 沈阳网络赛---gems gems gems(DP)

    题目链接 Problem Description Now there are n gems, each of which has its own value. Alice and Bob play a ...

  3. 2018 ICPC 沈阳网络赛

    2018 ICPC 沈阳网络赛 Call of Accepted 题目描述:求一个算式的最大值与最小值. solution 按普通算式计算方法做,只不过要同时记住最大值和最小值而已. Convex H ...

  4. HDU 6194 string string string 2017沈阳网络赛 后缀数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 题意:告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次. 解法:后缀数组 ...

  5. 2019 徐州网络赛 G Colorful String 回文树

    题目链接:https://nanti.jisuanke.com/t/41389 The value of a string sss is equal to the number of differen ...

  6. HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...

  7. HDU5853 Jong Hyok and String(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One da ...

  8. 沈阳网络赛 F - 上下界网络流

    "Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a ...

  9. HDU 3948 The Number of Palindromes(Manacher+后缀数组)

    题意 求一个字符串中本质不同的回文子串的个数. $ 1\leq |string| \leq 100000$ 思路 好像是回文自动机的裸题,但是可以用 \(\text{Manacher}\) (马拉车) ...

随机推荐

  1. C#控制台应用程序之旅游资源与线路管理系统

    利用C#语言及SQL Server数据库编写的一个简化版旅游资源与线路管理系统 数据库中包含三张表:hotel表.tourist_spot表.lines表 用户分为管理员和普通用户,管理员拥有最高权限 ...

  2. Redis主从复制(Master/Slave)

    Redis主从复制(Master/Slave) 修改配置文件 拷贝多个redis.conf文件分别配置如下参数: 开启daemonize yes pidfile port logfile dbfile ...

  3. 【.net 深呼吸】导出 Office 文档中的图片

    我们常用的 Office 文档其实就三种——Word.Excel.PowerPoint,分别对应的扩展名为:.docx..pptx..xlsx. 许多教程都告诉我们,要提取这些文件中的图片(其实像视频 ...

  4. C#去掉JSON字符串中的最后一个数字

    这个问题总结起来就是去掉字符串中的最后一个"," 字符串:string s = "1,2,3,4,5," 目标:删除最后一个 "," 方法: ...

  5. android项目数据库升级跨版本管理解决方案

    目前公司android项目普遍使用框架对数据库进行操作,数据库表与数据实体都具有严格的对应的关系,但是数据库的升依赖不同版本间的升级脚本,如果应用跨多版本进行升级时,当缺失部分升级脚本时就会导致应用异 ...

  6. Unity 继承MonoBehaviour脚本 执行顺序 详解

    先看结果 Awake ->OnEnable-> Start ->-> FixedUpdate-> Update  -> LateUpdate ->OnGUI ...

  7. javaWeb学习之tomcat服务器

    一.web a)        web结构 b)        常见的服务器 WebLogic: orcale公司的产品,支持JAVAEE规范,收费 WebsphereAS: IBM公司的产品 ,支持 ...

  8. C#+HtmlAgilityPack—>糗事百科桌面版V2.0

    最近在浏览以前自己上传的源码,发现在糗事百科桌面端源码评论区中,有人说现在程序不能用了.查看了一下源码运行情况,发现是正则表达式解析问题.由于糗百的网页版链接和网页格式稍有变化,导致解释失败.虽然可以 ...

  9. 安装完iis后本机用IP可以访问,别的电脑不能访问

    局域网IIS无法访问的解决方法 无法访问局域网内其它电脑中的IIS,自己可以访问,但别的电脑不行一般发生这种情况时操作系统是XP第二版. 具体操作如下:1.打开控制面版2.打开Windows防火墙 5 ...

  10. asp.net 开发 sql server 转 oracle

    前段时间我们公司项目 要把sql server 转oracle 分享一下心得 也记录一下问题 开始我研究了一段时间 然后下载了 oracle 11g 版本 和 PL/SQL(客户端) 和sql ser ...