题意:告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次。

解题思路:先用后缀数组进行算出height,然后用ST表维护,然后用区间长为k进行查询,找出最小的height,目的是为了找出k都有的字符串长度,然后区间往左右分别扩展一个单位,目的是看看左右的重复情况,左右的最大值,代表超出K的范围。要注意K=1时是一种特殊情况,具体看代码理解,已经注释。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#define N 505000
using namespace std;
char s[N];
int sa[N],t1[N],t2[N],c[N],rnk[N],height[N],n,p[N][30];
void build_sa(int m)
{int *x = t1, *y = t2;for(int i=0; i<m; i++) c[i] = 0;for(int i=0; i<n; i++) c[x[i] = s[i]]++;for(int i=1;i<m;i++) c[i]+=c[i-1];//桶 for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for(int k=1; k<=n; k = k<<1){int p = 0;//y是用来给第二关键字排序的 for(int i=n-k; i<n; i++) y[p++] = i; //后面几个第二关键字都没有,自然是最小的,排在前面 for(int i=0; i<n; i++) if(sa[i] >= k) y[p++] = sa[i]-k;//第二关键字的位置本来是sa[i],-k之后就变成它对应第一关键字的位置(直边所指) for(int i=0; i<m; i++) c[i] = 0;//清空桶,要开始基数排序了 for(int i=0; i<n; i++) c[x[y[i]]]++;for(int i=0; i<m; i++) c[i] += c[i-1];for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];swap(x,y);p = 1; x[sa[0]] = 0;//从0开始赋值 for(int i=1; i<n; i++)//如果说第一关键字和第二关键字都和前面相同,那就给一个和前面一样的键值,否则就给一个新的更高的键值 x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++;if(p >= n) break;//已经分出胜负了,各不相同 m = p;}
}
void getheight()
{int i,j,k = 0;for(int i=0; i<n; i++)  rnk[sa[i]] = i;for(i = 0; i < n; i++){if(k) k--;//h[i]>=h[i-1]-1 if(rnk[i] == 0){height[rnk[i]] = 0;continue;}j = sa[rnk[i]-1];while(s[i+k] == s[j+k]) k++;height[rnk[i]] = k;}
}
void build_st()
{for(int i=1;i<n;i++) p[i][0]=height[i];//必须从1开始,代表第一位 for(int j=1;j<=29;j++){for(int i=1;i+(1<<j)-1<n;i++){p[i][j]=min(p[i][j-1],p[i+(1<<(j-1))][j-1]);}}
}
int query(int l,int r)
{if(l>r) return n-sa[r]-1;//真的算的时候,要把最后0给除掉,因为本来这个0就是多余添加的,不除外就是当这个0是一开始就在字符串中了 int k=log2(r-l+1);//cout<<k<<" "<<l<<" "<<r<<"*"<<endl;return min(p[l][k],p[r-(1<<k)+1][k]);
}
int main()
{freopen("t.txt","r",stdin);int T,k;scanf("%d",&T);while(T--){scanf("%d",&k);scanf("%s",s);n=strlen(s);s[n++]=0;build_sa(128);getheight();for(int i=0;i<n;i++) printf("%d ",height[i]);printf("\n");build_st();int ans=0;k--;for(int i=1;i<n-k+1;i++){int l=i,r=i+k-1;int len=query(l,r);int more=max((l>1?query(l-1,r):0),(r<n-1?query(l,r+1):0));ans+=max(0,(len-more));}printf("%d\n",ans);}return 0;
}

HDU6194(后缀数组)相关推荐

  1. HDU6194 后缀数组的应用

    题目大意: 给你一个串,让你统计有多少个子串出现了恰好k次,可重复的子串. 分析: 第一道后缀数组的题目. 我们先求出sa数组和,height数组,然后我们不难发现,我们需要枚举区间k,在[i,i+k ...

  2. HDU6194 后缀数组

    简略题意:问在一个字符串中出现次数等于k次的子串有多少种. 考虑按kk对height进行分组,则当前分组对答案的贡献为: 组内所有元素的的max(0, LCP - max(组内第一个元素与之前元素的L ...

  3. HDU 6194 string string string 后缀数组 + RMQ(线段树)

    传送门:HDU6194 题意:问给定字符串中有多少种出现k次的子串. 思路:首先想到后缀数组经典问题,求出现不少于k次的子串的最大长度,类似的这题肯定就是在height数组上搞事情啦. 将height ...

  4. 寻找一个字符串的重复子串 后缀数组

    什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...

  5. 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]

    时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...

  6. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  7. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  8. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  9. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

最新文章

  1. c语言char转wchar t,c语言char和wchar_t 转换
  2. 邁向IT專家成功之路的三十則鐵律 鐵律十七:IT人休閒之道-清心
  3. Visual Studio下载、安装、运行教程
  4. VTK:Snippets之PointToGlyph
  5. linux ssh服务端下载文件,Linux SSH服务端配置文件设置
  6. linux命令积累之egrep命令
  7. idea怎么将本地文件和远程git对比_IDEA新建本地项目关联远程git仓库
  8. Xshell如何进行文件上传?
  9. Redis 中两种持久化机制详解
  10. 知物由学 |“网状世界”下,无处可逃的信息安全
  11. Spring-Bean配置-使用外部属性文件(转)
  12. C4996 'GetVersionExW': 被声明为已否决 TTS_one f:\vs2015\speechsdk\include\sphel
  13. 关于python文件打开模式表示错误的是_python文件读取失败了该怎么处理 !
  14. servlet生成验证码和点击刷新验证码
  15. 【渝粤教育】电大中专电商运营实操 (10)作业 题库
  16. NavMeshAgent参数及API
  17. 台式机单硬盘安装黑苹果体验
  18. 35岁的程序员:第18章,私欲
  19. dcos 正确的查看日志的姿势
  20. AI时代下,如何打造一个具有情感化属性的智能相册?

热门文章

  1. SAXReader saxReader = new SAXReader();来解析xml文件
  2. 这个vue3的应用框架你学习了吗?
  3. 已解决RuntimeError: CUDA error: device-side assert triggered异常的正确解决方法,亲测有效!!!
  4. ICA简介:独立成分分析
  5. 2020 第三届安洵杯 MISC Writeup
  6. hksi paper 1 香港证券资格考试卷一 备考经验分享(2022.10) 證券及期貨從業員資格考試
  7. 42-Map集合遍历键找值方式-键值对对象Entry-键值对方式遍历
  8. (读后摘抄)《计算机程序设计语言的发展》_王汝传
  9. leetcode-1786
  10. 如何在EXCEL中画横线并输入汉字