HDU_6194 后缀数组+RMQ
好绝望的。。想了五个多小时,最后还是没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的更多相关文章
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- POJ 3693 后缀数组+RMQ
思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #includ ...
- 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 ...
- HDU2459 后缀数组+RMQ
题目大意: 在原串中找到一个拥有连续相同子串最多的那个子串 比如dababababc中的abababab有4个连续的ab,是最多的 如果有同样多的输出字典序最小的那个 这里用后缀数组解决问题: 枚举连 ...
- hdu 2459 (后缀数组+RMQ)
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...
- ural 1297(后缀数组+RMQ)
题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能 ...
- 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)
3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...
- 【poj3693】Maximum repetition substring(后缀数组+RMQ)
题意:给定一个字符串,求重复次数最多的连续重复子串. 传说中的后缀数组神题,蒟蒻真的调了很久才对啊.感觉对后缀数组和RMQ的模版都不是很熟,导致还是会有很多各种各样的小错误= = 首先,枚举重复子串的 ...
- 【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 ...
随机推荐
- Vue系列(2):Vue 安装
前言:关于页面上的知识点,如有侵权,请看 这里 . 关键词:小白.Vue 安装.Vue目录结构.Vue 构建页面流程 ? 初学者安装 vue 用什么好 大家都知道,学 Vue 最好还是去官网学,官网写 ...
- TAS5508 output changing
1.如果信号从3th通道输入,正常就是从PWM5,6输出,现在要想从PWM7,8输出,就按照以下红线部分选择DAP CH5和DAP CH6,然后写入相应寄存器产生的12 bytes的数组数据即可.
- datagrid数据表格使用总结
一.加载的css文件 easyui 基本样式: <link href="../easyui/easyui1.5.css" rel="stylesheet" ...
- A011 Activiti工作流程开发的一些统一规则和实现原理(完整版)
注意:以下规则是我为了规范流程的处理过程,不是Activiti公司的官方规定. 1.流程启动需要设置启动者,在Demo程序中,“启动者变量”名统一设置为initUserId 启动时要做的: ident ...
- java核心技术 要点笔记2
第4章 对象和类 1.面向对象 类:构造对象的模板,创建类的实例:由类构造对象的过程,封装,继承: 对象:对象的特性——对象的行为,对象的状态,对象的标识: 类之间的关系: 依赖(“user-a” ...
- linux 命令——15 tail (转)
tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新, ...
- 汶川大地震中的SAP成都研究院
5·12汶川地震,发生于北京时间(UTC+8)2008年5月12日(星期一)14时28分04秒,此次地震的面波震级 里氏震级达8.0Ms.矩震级达8.3Mw,地震烈度达到11度.地震波及大半个中国及亚 ...
- codeforces 600C Make Palindrome
要保证变化次数最少就是出现次数为奇数的相互转化,而且对应字母只改变一次.保证字典序小就是字典序大的字母变成字典序小的字母. 长度n为偶数时候,次数为奇数的有偶数个,按照上面说的搞就好了. n为奇数时, ...
- [超详细] Python3爬取豆瓣影评、去停用词、词云图、评论关键词绘图处理
爬取豆瓣电影<大侦探皮卡丘>的影评,并做词云图和关键词绘图第一步:找到评论的网页url.https://movie.douban.com/subject/26835471/comments ...
- IntelliJ IDEA中激活JRebel插件
1. 下载激活软件:https://github.com/ilanyu/ReverseProxy/releases/tag/v1.0 我下载的是 2. 双击文件运行 3. 点击change licen ...