题目链接

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. java考试易错题大全

    常见的Java问题 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Ja ...

  2. 自定义Git之忽略特殊文件

    有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定 ...

  3. web端常见安全漏洞测试结果分析-- appscan

    基于appscan测试结果分析: 一.XSS跨站脚本 指的是攻击者往Web页面里插入恶意html代码,通常是JavaScript编写的恶意代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被 ...

  4. Unity Editor 检查工程Prefab(预设)中的空组件

    在我们做项目的过程中 经常会有预设中出现空的脚本 例如: 导致的原因是因为 脚本的丢失 现在我们来做一个检查工程中有空脚本的预设工具 老规矩直接上代码 放到工程就能用 using UnityEngin ...

  5. 【HOSTS相关】什么时候使用127.0.0.1

    什么时候使用127.0.0.1 在测试环境,如果想知道上线后服务发生异常中断的情况下界面会如何展示,这个时候有2种方式: 第1种是:由开发人员协助,比如后台开发人员在服务器上使这个服务停止,或者由前端 ...

  6. Vue组件选项props

    前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props ...

  7. react-native学习路线总结

    本人新手web前端程序员一枚,应公司要求学习React-native框架,作为博客萌新来讲讲我这一个月学习历程,新人和前端的朋友们可以一看,其他都可看,反正不用你掏钱啊. 首先当然还是介绍一下reac ...

  8. LINUX系统自动化部署shell脚本

    #!/bin/shsudo /etc/init.d/tomcatstopwaitsudo rm -rf /opt/tomcat7/work/*waitsudo rm -rf /opt/tomcat7/ ...

  9. Linux Socket多线程实现简单的多人聊天(pend)

    Server: 设置可聊天数为5,为每一个client创建一个线程,这个线程负责接收client的聊天内容并发给其他用户看. 用mutex同步各个线程修改聊天室空余聊天位. Client: 主线程负责 ...

  10. iOS之Cocoapods安装

    网上关于cocoapods的教程很多,关于它的优点我不赘述:但是我根据多次安装的经验,把我遇到的问题写一下,希望对新手有所帮助. 1. 设置输入源(由于默认的gem资源是国外的,由于历史原因,访问比较 ...