FZU-2075 Substring(后缀数组)
Description
Input
Output
Sample Input
2
ababba
Sample Output
ab 题目大意:给一个字符串,找出其恰好出现n次的字典序最小的子串。
题目分析:将所有的子串排序后,定义n块为相邻的n个子串构成的字符串集合,如果某个n块的lca大于包含它的n+1块的lca,那么这个n块的lca便是恰好出现了n次的子串。 代码如下:
//# define AC # ifndef AC # include<iostream>
# include<cstdio>
# include<cstring>
# include<vector>
# include<queue>
# include<list>
# include<cmath>
# include<set>
# include<map>
# include<string>
# include<cstdlib>
# include<algorithm>
using namespace std; const int N=100000; int SA[N+5];
int tSA[N+5];
int rk[N+5];
int cnt[N+5];
int height[N+5];
int *x,*y; bool same(int i,int j,int k,int n)
{
if(y[i]!=y[j]) return false;
if(i+k<n&&j+k>=n) return false;
if(i+k>=n&&j+k<n) return false;
return y[i+k]==y[j+k];
} void buildSA(char* s)
{
x=rk,y=tSA;
int m=130;
int n=strlen(s);
for(int i=0;i<m;++i) cnt[i]=0;
for(int i=0;i<n;++i) ++cnt[x[i]=s[i]];
for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;--i) SA[--cnt[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) cnt[i]=0;
for(int i=0;i<n;++i) ++cnt[x[y[i]]];
for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;--i) SA[--cnt[x[y[i]]]]=y[i]; p=1;
swap(x,y);
x[SA[0]]=0;
for(int i=1;i<n;++i)
x[SA[i]]=same(SA[i],SA[i-1],k,n)?p-1:p++;
if(p>=n) break;
m=p;
}
} void getHeight(char* s)
{
int n=strlen(s);
int k=0;
for(int i=0;i<n;++i) rk[SA[i]]=i;
for(int i=0;i<n;++i){
if(rk[i]==0)
height[rk[i]]=k=0;
else{
if(k) --k;
int j=SA[rk[i]-1];
while(s[i+k]==s[j+k]) ++k;
height[rk[i]]=k;
}
}
} char s[N+5];
int st[N+5][20]; void spare_table()
{
int n=strlen(s);
for(int i=1;i<n;++i)
st[i][0]=height[i];
for(int k=1;(1<<k)<=n;++k){
for(int i=1;i+(1<<k)-1<n;++i){
st[i][k]=min(st[i][k-1],st[i+(1<<(k-1))][k-1]);
}
}
} int getST(int l,int r)
{
int k=0;
while((1<<(k+1))<=r-l+1) ++k;
return min(st[l][k],st[r-(1<<k)+1][k]);
} string solve(int m)
{
string res="";
int n=strlen(s);
int a,b,c;
for(int i=0;i+m-1<n;++i){
a=b=c=0;
if(m==1) a=n-SA[i];
else a=getST(i+1,i+m-1);
if(i+m<n) b=getST(i+1,i+m);
if(i>0) c=getST(i,i+m-1);
if(a>b&&a>c){
for(int j=SA[i];j<SA[i]+a;++j) res+=s[j];
return res;
}
}
return "impossible";
} int main()
{
int m;
while(~scanf("%d",&m))
{
scanf("%s",s);
buildSA(s);
getHeight(s);
spare_table();
cout<<solve(m)<<endl;
}
return 0;
} # endif
FZU-2075 Substring(后缀数组)的更多相关文章
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- HDU 5769 Substring 后缀数组
Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...
- HDU 5679 Substring 后缀数组判重
题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...
- hdu_1403_Longest Common Substring(后缀数组的应用)
题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- 2016多校联合训练4 F - Substring 后缀数组
Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...
- hdu 5769 Substring 后缀数组 + KMP
http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解 ...
- Substring (后缀数组 + 计数)
题意:求出字符串中包含了某个字符的字符序列不一样的数量. 思路:其实主要的是找出每个被包含字符的数量,假设除了目标字符之外的所有字符都不一样,那么应该就很好求了,但是显然不可能,所以我们可以枚举每一个 ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...
随机推荐
- android 加载中、无网络、无数据、出错 四种状态的代码封装
package com.weavey.loading.lib;import android.content.Context;import android.content.res.TypedArray; ...
- JS设置弹出小窗口。
经常上网的朋友可能会到过这样一些网站,一进入首页立刻会弹出一个窗口,或者按一个连接或按钮弹出,通常在这个窗口里会显示一些注意事项.版权信息.警告.欢迎光顾之类的话或者作者想要特别提示的信息.其实制作这 ...
- 解决Inno Setup制作中文安装包在非中文系统上显示乱码的问题
尼玛,好几个月没更新了.囧... 目前我司新的客户端开发已经接近尾声,该改的bug已经改完,该重构的地方也都差不多了.视觉效果也已经根据美工的样式改完了.所以,就差制作安装包了.正所谓万事俱备,只欠东 ...
- Hadoop:输入,输出,key,value格式
map: (K1, V1) → list(K2, V2) reduce: (K2, list(V2)) → list(K3, V3) (K1, V1): jobConf.setInputKeyClas ...
- Cocoapods的安装
1.先升级Gem sudo gem update --system 2.切换cocoapods的数据源 [先删除,再添加,查看] gem sources --remove https://rubyge ...
- 六大免费网站数据采集器对比(火车头,海纳,云采集,ET,三人行,狂人采集)
2013年02月27日 PHP开源系统 暂无评论 阅读 497 views 次 在目前的站长圈内,比较流行的采集工具有很多,但是总结起来,比较出名的免费的就这么几个:火车头,海纳,云采集,ET,三人行 ...
- android最常用的退出方法
public class AppUtils extends Application{ private List<Activity> activityList = new LinkedLis ...
- Quartz Core框架之CALayer
1.继承链:NSObject 2.创建一个layer (1)+ (instancetype)layer :创建和返回一个layer实例对象 (2)- (instancetype)init :返回一个初 ...
- 2016-08-05(1) ng-options的用法详解
http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/ng-options-usage/
- Java基础一
这是在网上找的知识点 覆盖方法必须满足的条件: 1)子类方法的名称.参数签名和返回类型必须与父类方法的名称.参数签名和返回类型一致,修饰符可以相同也可以不同,但子类的访问权限不能低于父类的访问权限. ...