好绝望的。。想了五个多小时,最后还是没A。。。赛后看了下后缀数组瞬间就有了思路。。。不过因为太菜,想了将近两个小时才吧这个题干掉。

首先,应当认为,后缀数组的定义是,某字符串S的所有后缀按照字典序有小到大的顺序排列(使用下标表示后缀)。因为具体过程没太看懂,但是参见刘汝佳蓝书《算法竞赛黑暗圣典》可以得到一个聪明的NLOGN的神器算法。不过这个不太重要。

之后还可以通过他在LCP问题中提到的RANK,height数组相关算法,处理出来height数组,之后其他的可以扔掉。

《黑暗圣典》中定义了height数组,height[k]的含义是,第rank[i]数组和rank[i]-1之间的最长公共前缀的长度。。。基于这个我们可以看到一些规则。

首先height数组的定义具有传递性,很容易想到的就是。。。出现且仅出现M次可以被简单的定义为,传递且仅能够被传递M次。。。

于是。。。我们有了如下算法.

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const long long MAXN=;
const long long INF=1E8+;
char s[MAXN];
//long long dp[MAXN];
long long sa[MAXN],t[MAXN],t2[MAXN],c[MAXN],n,len;
long long r1ank[MAXN],height[MAXN];
long long d[MAXN][];
void RMQ_init()
{
for(int i=;i<n;++i)d[i][]=height[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<n;i++)
d[i][j]=min(d[i][j-],d[i+(<<(j-))][j-]);
}
long long RMQ(int a,int b)
{
int k=;
while((<<(k+))<=b-a+)k++;
return min(d[a][k],d[b-(<<k)+][k]);
} int m;
void build_sa(int m)
{
long long i,*x=t,*y=t2;
for( i=;i<m;++i)c[i]=;
for( i=;i<n;++i)c[x[i]=s[i]]++;
for( i=;i<m;++i)c[i]+=c[i-];
for( i=n-;i>=;i--)sa[--c[x[i]]]=i;
for( int k=;k<= n ;k*=)
{
int p=;
for(i=n-k;i<n;++i)y[p++]=i;
for(i=;i<n;++i)if(sa[i]>=k)y[p++]=sa[i]-k; for( i=;i<m;++i)c[i]=;
for( i=;i<n;++i)c[x[y[i]]]++;
for( i=;i<m;++i)c[i]+=c[i-];
for( i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i]; swap(x,y);
p=;x[sa[]]=;
for( i=;i<n;++i)
{
x[sa[i]]=y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k]?p-:p++;
}if(p>=n)break;
m=p;
}
}
void getHeight()
{
int i,j,k=;
for(int i=;i<n;++i)r1ank[sa[i]]=i;
for(int i=;i<n;++i)
{
if(k)k--;
int j=sa[r1ank[i]-];
while(s[j+k]==s[i+k])k++;
height[r1ank[i]]=k;
}
height[n]=;
} int main()
{
int t;cin>>t; while(t--)
{
// memset(height,0,sizeof(height));
scanf("%d %s",&m,s);
n=strlen(s);
len=n;n+=;;
build_sa();
getHeight();
RMQ_init();long long ans=;
for(int i=;i<n;++i)
{
if(m==)
{
ans+=len-sa[i]-max(height[i],height[i+]);
continue;
}
int a=i+;int b=i+m-;
long long limit=RMQ(a,b);
if(n>b&&limit>max(height[i],height[b+]))ans+=limit-max(height[i],height[b+]); }
cout<<ans<<"\n";
} }

HDU_6194 后缀数组+RMQ的更多相关文章

  1. 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过

    题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...

  2. POJ 3693 后缀数组+RMQ

    思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #includ ...

  3. spoj687 REPEATS - Repeats (后缀数组+rmq)

    A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed strin ...

  4. HDU2459 后缀数组+RMQ

    题目大意: 在原串中找到一个拥有连续相同子串最多的那个子串 比如dababababc中的abababab有4个连续的ab,是最多的 如果有同样多的输出字典序最小的那个 这里用后缀数组解决问题: 枚举连 ...

  5. hdu 2459 (后缀数组+RMQ)

    题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...

  6. ural 1297(后缀数组+RMQ)

    题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能 ...

  7. 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)

    3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...

  8. 【poj3693】Maximum repetition substring(后缀数组+RMQ)

    题意:给定一个字符串,求重复次数最多的连续重复子串. 传说中的后缀数组神题,蒟蒻真的调了很久才对啊.感觉对后缀数组和RMQ的模版都不是很熟,导致还是会有很多各种各样的小错误= = 首先,枚举重复子串的 ...

  9. 【HDU3948】 The Number of Palindromes (后缀数组+RMQ)

    The Number of Palindromes Problem Description Now, you are given a string S. We want to know how man ...

随机推荐

  1. Laravel项目的结构文章

    http://esbenp.github.io/2016/04/11/modern-rest-api-laravel-part-1/

  2. spring mvc <mvc;resources>

    spring mvc 的<mvc;resources mapping="***" location="***">标签是在spring3.0.4出现的 ...

  3. aar、jar、so的引入和aar打包包含so、aar、jar文件

    so依赖   1,先建本地仓库,指向so放置的目录

  4. Spring IoC和AOP的介绍

    基于Spring Framework 版本:5.0.2.RELEASE IoC 概念:传统Java开发中,程序通过new主动创建对象实例,而Spring有专门的IoC容器来创建对象,具体来说就是在Sp ...

  5. shell中的数值计算1/3=0.33

    方法1:使用bc工具,把结果printf格式化 res=$(printf "%.5f" `echo "scale=5;1/3"|bc`) echo $res 0 ...

  6. CST,CET,UTC,GMT,DST,Unix时间戳几种常见时间概述与关系(转)

    转自:http://www.cnblogs.com/frontendBY/p/5215785.html 1.UTC: Universal Time Coordinated 协调世界时,又称世界标准时间 ...

  7. python3.7 安装 xlrd 模块---Mac

    要用Excel将数据和代码分离,需要import xlrd, 使用前需要先安装xlrd模块. 说明:通过在google中搜索“xlrd Mac”,下载xlrd.py模块(下载地址:http://mac ...

  8. 当您在 64 位 Windows 上运行 Regsvr32.exe 时出现错误信息

    尝试运行 Regsvr32.exe 注册在 64 位版本的 Windows 32 位动态链接库 (DLL) 时您会收到以下错误消息: 若要解决此问题,从 %SystemRoot%\Syswow64 文 ...

  9. js高级笔录

    1.类型转换①转换成字符串toString() ⅰBoolean 值.数字和字符串的原始值的有趣之处在于它们是伪对象,这意味着它们实际上具有属性和方法. var sColor = "red& ...

  10. fiddle连接终端测试配置

    第一次做app,对app的数据要进行一些数据抓包和数据分析,知道客户端发送到服务器端的过程和逻辑,通过抓包了解和分析出错,前提要先连接fiddle