HDU 6194 后缀数组
string string string
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1850 Accepted Submission(s): 546
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.
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.
9
代码:
//我们考虑每一个子串对结果的贡献,每个子串都是某个后缀的前缀,我们得到heigh数组之后可以维护一个长度是k的窗口,这个窗口中的后缀的
//lcp必然出现至少k次,然后再依次减去窗口左右端分别延长一位的lcp(即减去出现次数多于k次的lcp),这样他们中间的公共部分减了两次再加
//上就行了。注意临界端点的处理!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=;
int sa[MAXN+],ra[MAXN+],he[MAXN+],xx[MAXN+],yy[MAXN+],buc[MAXN+];
char s[MAXN+];
int len,m,f[MAXN+][];
void get_suf()
{
int *x=xx,*y=yy;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[i]=s[i]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[i]]]=i;
for(int k=;k<=len;k<<=){
int p=;
for(int i=len-;i>=len-k;i--) y[p++]=i;
for(int i=;i<len;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[y[i]]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[y[i]]]]=y[i];
swap(x,y);
p=;x[sa[]]=;
for(int i=;i<len;i++){
if(y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k])
x[sa[i]]=p-;
else x[sa[i]]=p++;
}
if(p>=len) break;
m=p;
}
for(int i=;i<len;i++) ra[sa[i]]=i;
int k=;
for(int i=;i<len;i++){
if(ra[i]==) { he[]=; continue; }
if(k) k--;
int j=sa[ra[i]-];
while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++;
he[ra[i]]=k;
}
}
void rmq1()
{
for(int i=;i<=len;i++)
f[i][]=he[i];
for(int j=;(<<j)<=len;j++){
for(int i=;i+(<<j)-<=len;i++)
f[i][j]=min(f[i][j-],f[i+(<<(j-))][j-]);
}
}
int query(int l,int k)
{
if(l<||l+k->=len) return ;
if(k==) return len-sa[l];
int j=,r=l+k-;l++;
while(<<(j+)<=r-l+) j++;
return min(f[l][j],f[r-(<<j)+][j]);
}
int main()
{
//freopen("in.txt","r",stdin);
int t,k;
scanf("%d",&t);
while(t--){
scanf("%d",&k);
scanf("%s",s);
len=strlen(s);
m=;
get_suf();
he[]=he[len]=;
rmq1();
int ans=;
for(int i=;i+k-<len;i++)
ans+=query(i,k)-query(i-,k+)-query(i,k+)+query(i-,k+);
printf("%d\n",ans);
}
return ;
}
HDU 6194 后缀数组的更多相关文章
- hdu 3948 后缀数组
The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (J ...
- HDU - 3948 后缀数组+Manacher
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意:给定一个字符串,求字符串本质不同的回文子串个数. 思路:主要参考该篇解题报告 先按照man ...
- HDU 5769 后缀数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5769 [2016多校contest-4] 题意:给定一个字符,还有一个字符串,问这个字符串存在多少个不 ...
- hdu 2459 (后缀数组+RMQ)
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...
- hdu 3518(后缀数组)
题意:容易理解... 分析:这是我做的后缀数组第一题,做这个题只需要知道后缀数组中height数组代表的是什么就差不多会做了,height[i]表示排名第i的后缀与排名第i-1的后缀的最长公共前缀,然 ...
- hdu 5442 (后缀数组)
稍微学习了下第一次用后缀数组- - , 强行凑出答案 , 感觉现在最大的问题是很多算法都不知道 ,导致有的题一点头绪都没有(就像本题). /*推荐 <后缀数组——处理字符串的有力工具>— ...
- HDU 5558 后缀数组
思路: 这是一个错误的思路, 因为数据水才过= = 首先求出来后缀数组 把rank插到set里 每回差i两边离i近的rank值,更新 如果LCP相同,暴力左(右)继续更新sa的最小值 //By Sir ...
- HDU 4691 后缀数组+RMQ
思路: 求一发后缀数组,求个LCP 就好了 注意数字有可能不只一位 (样例2) //By SiriusRen #include <bits/stdc++.h> using namespac ...
- K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)
大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...
随机推荐
- 5.airflow问题
1. Traceback (most recent call last): File "/usr/bin/airflow", line 28, in <module> ...
- selenium--判断元素是否存在
# coding:utf-8from selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitf ...
- mysql 设置远程登录
1.本机登录进mysql,并切换到本机mysql数据库下 2. GRANT ALL PRIVILEGES ON *.* TO 'tigase'@'%' IDENTIFIED BY '123456' W ...
- .NET Core 控制台中文乱码问题!
class Program { static void Main(string[] args) { Encoding.RegisterProvider(CodePagesEncodingProvide ...
- 使用字符界面 qemu-kvm 创建虚拟机
qemu-kvm的基本用法:指定系统类型,CPU运行模式,NUMA(Non Uniform Memory Access Architecture), 软驱设备,光驱设备,硬件设备 # 查看qemu ...
- 【leetcode】300.Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- SSH框架配置
--------------------------------applicationContext.xml-------------------------------- <?xml vers ...
- Linux服务器启动后只读解决办法
今天处理一个服务器,远程死活连接不上,只好跑信息中心去看了下服务器. Linux服务器启动之后,提示: give root password for maintenance (or type cont ...
- ACM解题之在线翻译 Give Me the Number
Give Me the Number Time Limit: 2 Seconds Memory Limit: 65536 KB ...
- Filter2D卷积运算
图像处理中的卷积运算一般都用来平滑图像.尖锐图像求边缘等等.主要看你选择什么样的核函数了.现在核函数很多,比如高斯平滑核函数,sobel核函数,canny核函数等等.这里举一个sobel核函数的例子来 ...