题目大意:
给你一个串,让你统计有多少个子串出现了恰好k次,可重复的子串。
分析:
第一道后缀数组的题目。
我们先求出sa数组和,height数组,然后我们不难发现,我们需要枚举区间k,在[i,i+k-1]这个区间里面去求sa[i,i+k-1]的最长公共前缀,这样就求出来了至少出现k次的子串,然后我们需要去减去至少出现k+1次的子串,所以要减去[i-1,i+k-1]和[i,i+k]的,但是这样又把[i-1,i-k]的减多了一次,在加上即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <stack>
using namespace std;
const int maxn = 1e5 + 10;
char s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn];
void build_sa(int m,int n)
{int i,*x=t,*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<<=1){int p=0;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;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;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;}
}
int ran[maxn],height[maxn];
void getheight(int n)
{//cout<<111<<endl;int i,j,k=0;for(i=0;i<=n;i++) ran[sa[i]]=i;for(i=0;i<n;i++){if(k) k--;j=sa[ran[i]-1];while(s[i+k]==s[j+k]) k++;height[ran[i]]=k;}
}
int d[maxn][20];
int n;
void rmq_init(int *A)
{for(int i=0;i<n;i++) d[i][0]=A[i];for(int j=1;(1<<j)<=n;j++){for(int i=0;i+(1<<j)-1<n;i++){d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);}}
}
int rmq(int L,int R)
{int k=0;while((1<<(k+1))<=R-L+1) k++;return min(d[L][k],d[R-(1<<k)+1][k]);
}
int query_rmq(int l,int r)
{if(l==r) return n-sa[l];return rmq(l+1,r);
}
int main()
{int T;scanf("%d",&T);while(T--){int k;scanf("%d",&k);scanf("%s",s);n=strlen(s);build_sa(200,n+1);getheight(n);for(int i=1;i<=n;i++){height[i-1]=height[i];}for(int i=0;i<n;i++){sa[i]=sa[i+1];//cout<<sa[i]<<endl;}int ans=0;rmq_init(height);
//        cout<<rmq(0,1)<<"...."<<endl;for(int i=0;i<n;i++){int j=i+k-1;if(j>=n) break;ans+=query_rmq(i,j);//   cout<<ans<<"  111"<<endl;if(i-1>=0) ans-=query_rmq(i-1,j);//cout<<ans<<"  222"<<endl;if(j+1<n)  ans-=query_rmq(i,j+1);// cout<<ans<<"  333"<<endl;if(i-1>=0&&j+1<n) ans+=query_rmq(i-1,j+1);// cout<<ans<<endl;}printf("%d\n",ans);}return 0;
}

HDU6194 后缀数组的应用相关推荐

  1. HDU6194(后缀数组)

    题意:告诉你一个字符串和k , 求这个字符串中有多少不同的子串恰好出现了k 次. 解题思路:先用后缀数组进行算出height,然后用ST表维护,然后用区间长为k进行查询,找出最小的height,目的是 ...

  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. 汇编:JCXZ条件转移指令
  2. Redis Scan命令
  3. 基于linux-2.6.35的class_create(),device_create解析
  4. html5 漏洞,HTML 5漏洞可致硬盘遭垃圾数据填满
  5. 【记录】idea创建springboot多模块项目
  6. 关于Tomcat导致工程部分功能代码异常的问题
  7. Java里进制转换(二进制、八进制、十进制、十六进制)
  8. PaddlePaddle飞桨OCR文本检测——入门安装GPU版(一)
  9. python与excel-Python 与 Excel 终于在一起了
  10. matlab 均值滤波
  11. IIS6/IIS7无法打开IIS管理器的解决方法。
  12. 用python计算100以内的素数_python如何求100以内的素数
  13. 异步社区本周新上电子书
  14. 最新最全的微信小程序入门学习教程,微信小程序零基础入门到精通
  15. 百度地图api 城市代码(citycode)
  16. mysql sniffer数据库审计_MySQL抓包工具:MySQL Sniffer
  17. 美国卡内基梅隆大学计算机排名,美国卡内基梅隆大学世界排名情况
  18. 黑客用“勒索病毒”展示肌肉,但你了解什么是“白帽黑客”吗?
  19. 《计算机是怎样跑起来的》读书笔记
  20. 别惊讶,我真的不建议你考华为认证,点进来看原因~

热门文章

  1. poi 读取word 遍历表格和单元格中的图片
  2. matlab中三角函数sin、cos、tan以弧度为单位
  3. JAVA对象布局之对象头(Object Header)
  4. 导航栏: UINavigationBar用法
  5. Solr学习 DIH增量、定时导入并检索数据
  6. node.js卸载与重装
  7. [玩转编程] C语言+模拟器制作简单脚本
  8. 如何计算CAN通信波特率
  9. 华擎主板bios设置图解_华擎主板BIOS设置程序手册.pdf
  10. jmeter基础(二)-JMeter证书