第一道后缀数组

后缀数组要维护三个数组:sa(suffix array), rk(rank)和ht(height)。

含义分别是:

sa[i]:将后缀按照字典序排序后,第i大的后缀的起始位置。

rk[i]:起始位置为i的后缀的排名。

ht[i]:起始位置为i的后缀与排名为rk[i]-1的后缀的最长公共前缀。

对于任意一个字串,一定是某个后缀的前缀。

然后从sa[1]开始,统计字串,每个后缀sa[i]的可能的字串的个数(不与前面统计的重复)是:n-sa[i]+1-ht[sa[i]]

然后就这羊枚举子串,幷向后暴力统计个数,这样还能保证字典序是从小到大。

 /**************************************************************
Problem: 2251
User: idy002
Language: C++
Result: Accepted
Time:240 ms
Memory:892 kb
****************************************************************/ #include <cstdio>
#define maxn 3010 int n;
int aa[maxn];
int sa[][maxn], rk[][maxn], ht[maxn], vv[maxn], p;
char str[maxn]; void expand( int k, int sa[maxn], int rk[maxn], int tsa[maxn], int trk[maxn] ) {
for( int i=; i<=n; i++ ) vv[rk[sa[i]]]=i;
for( int i=n; i>=; i-- ) if( sa[i]>k ) tsa[vv[rk[sa[i]-k]]--]=sa[i]-k;
for( int i=n-k+; i<=n; i++ ) tsa[vv[rk[i]]--]=i;
for( int i=; i<=n; i++ ) trk[tsa[i]]=trk[tsa[i-]]+(rk[tsa[i]]!=rk[tsa[i-]]||rk[tsa[i]+k]!=rk[tsa[i-]+k]);
}
void makeht() {
int k=;
ht[sa[p][]] = ;
for( int i=; i<=n; i++ ) {
if( rk[p][i]== ) continue;
int j=sa[p][rk[p][i]-];
while( aa[i+k]==aa[j+k] ) k++;
ht[i] = k;
if( k> ) k--;
}
}
void suffix() {
p=;
for( int i=; i<=n; i++ ) vv[aa[i]]++;
for( int i=; i<=; i++ ) vv[i]+=vv[i-];
for( int i=n; i>=; i-- ) sa[p][vv[aa[i]]--]=i;
for( int i=; i<=n; i++ ) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(aa[sa[p][i]]!=aa[sa[p][i-]]);
for( int k=; k<n; k<<=,p=-p ) expand( k, sa[p], rk[p], sa[-p], rk[-p] );
makeht();
} int main() {
scanf( "%d", &n );
scanf( "%s", str+ );
for( int i=; i<=n; i++ )
aa[i] = str[i]-''+;
suffix();
for( int i=; i<=n; i++ ) {
for( int t=sa[p][i]+ht[sa[p][i]]; t<=n; t++ ) {
int cnt=;
for( int j=i+; j<=n && ht[sa[p][j]]>=(t-sa[p][i]+); j++,cnt++);
if( cnt> )
printf( "%d\n", cnt );
}
}
}

bzoj 2251的更多相关文章

  1. bzoj 2251: [2010Beijing Wc]外星联络 后缀数组

    2251: [2010Beijing Wc]外星联络 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 424  Solved: 232[Submit][ ...

  2. ●BZOJ 2251 [2010Beijing Wc]外星联络

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2251 题解: 后缀数组,倍增,RMQ 题意:把重复次数超过 1次的子串按字典序输出它们重复的 ...

  3. BZOJ 2251: [2010Beijing Wc]外星联络

    2251: [2010Beijing Wc]外星联络 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 795  Solved: 477[Submit][ ...

  4. bzoj 2251: 外星联络 后缀Trie

    题目大意 http://www.lydsy.com/JudgeOnline/problem.php?id=2251 题解 本来以为这道题应该从01序列的性质入手 结果就想歪了 等自己跳出了01序列这个 ...

  5. bzoj 2251: [2010Beijing Wc]外星联络【SA】

    先求SA,然后按字典序从小到大枚举子串,每到一个后缀从长到短枚举子串(跳过长为he[i]的和前一段重复的子串),然后维护一个点p,保证i~p之间最小的he>=当前枚举长度,p是单调向右移的 然后 ...

  6. 外星联络(bzoj 2251)

    Description 小 P 在看过电影<超时空接触>(Contact)之后被深深的打动,决心致力于寻找外星人的事业.于是,他每天晚上都爬在屋顶上试图用自己的收音机收听外星人发来的信息. ...

  7. BZOJ 2251 Trie树

    思路: i~n加到Trie树里 经过的边权+1 DFS一遍 搞定~ //By SiriusRen #include <cstdio> #include <cstring> #i ...

  8. Week Four

    2018.12.18 1.[USACO Platinum C] 2.[Gym 102028H] 3.[BZOJ 2750] 4.[BZOJ 3238] 5.[BZOJ 4310] 6.[BZOJ 38 ...

  9. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

随机推荐

  1. NYOJ 2 括号配对问题 (模拟)

    题目链接 描述 现在,有一行括号序列,请你检查这行括号是否配对. 输入 第一行输入一个数N(0<N<=100),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个字符串S ...

  2. 25、Python垃圾回收机制?

    Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾.在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的 ...

  3. 教你如何修改FireFox打开新标签页(NewTab Page)的行列数

    FireFox的打开新建标签页(即NewTab Page)默认只能显示3x3个网站缩略图,这9个自定义的网站,非常方便快捷,什么hao123的弱爆了,本人从未用过此类导航网站,曾经用过的也只是abou ...

  4. eclipse 常见问题之字体更改、添加注释模板

    有些同学可能会和我有一样的困扰,每次想要更改字体大小.背景颜色等,都需要百度一下才知道怎么去做...不知道有没有这种情况的孩子,反正我经常遇到,老是记不住,今天写下来,顺带自己忘记的时候可以查看一下. ...

  5. Linux/Unix 怎样找出并删除某一时间点的文件

    Linux/Unix 怎样找出并删除某一时间点的文件 在Linux/Unix系统中,我们的应用每天会产生日志文件,每天也会备份应用程序和数据库,日志文件和备份文件长时间积累会占用大量的存储空间,而有些 ...

  6. 简单优化:Zipalign

    Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化.在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率.因此,这种方式 ...

  7. Linux命令之dig命令实例讲解

    1.查看域名的A记录 # dig yahoo.com; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.2 <<> ...

  8. 洛谷 P2077 红绿灯 题解

    题目传送门 这道题一秒一秒的扫描一定会超时,所以就用一种O(N)的算法. #include<bits/stdc++.h> using namespace std; ],b[],c[],x= ...

  9. 取消cp确认

    使用cp -r -f 强制覆盖拷贝命令时,每一个文件都需要认为的键入“Y”进行确认 可以通过取消同名cp的定义,命令如下unalias cp

  10. Python中列表的各种方法

    列表是Python中一种常用的存储信息的方式,所以要熟练掌握列表的各种方法: 首先我们定义一个列表(name),然后练习里面的各种方法: >>> name = ["Sora ...