题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12580

【思路】

求出现次数不小于k次的最长可重叠子串和最后的出现位置。

法一:

后缀数组,二分长度,划分height。时间复杂度为O(nlogn)

法二:

Hash法。构造字符串的hash函数,二分长度,求出hash(i,L)后排序,判断是否存在超过k个相同hash 值得块即可。时间为O(nlog2n).

    法三:(UPD.16/4/6)

     SAM。求|right|。

注意划分height一定要精确且如果m=1需要特判

【代码1】

 //193ms
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; const int maxn = +; int s[maxn];
int sa[maxn],c[maxn],t[maxn],t2[maxn];
void build_sa(int m,int n) {
int 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;
}
}
int rank[maxn],height[maxn];
void getHeight(int n) {
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;i++) {
if(k) k--;
j=sa[rank[i]-];
while(s[j+k]==s[i+k]) k++;
height[rank[i]]=k;
}
}
int limit,n,pos;
bool can(int L) { //一定要注意划分height数组的准确性
pos=-;
int cnt=,mx=sa[];
for(int i=;i<=n;i++) {
mx=max(mx,sa[i]);
if(height[i]<L) cnt=,mx=sa[i];
else {
if(++cnt>=limit) pos=max(pos,mx);
}
}
return pos>=;
} char expr[maxn];
int main() {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
while(scanf("%d",&limit)== && limit) {
scanf("%s",expr);
n=strlen(expr);
for(int i=;i<n;i++) s[i]=expr[i]; s[n]=; build_sa('z'+,n+);
getHeight(n); if(limit==) { printf("%d 0\n",n); continue; }
int L=,R=n+;
while(L<R) {
int M=L+(R-L+)/;
if(can(M)) L=M; else R=M-;
}
if(!can(L)) printf("none\n");
else printf("%d %d\n",L,pos);
}
return ;
}

da

【代码2】

 //1628ms
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; typedef unsigned long long ULL;
const int maxn = +;
const int x = ; ULL hash[maxn],xp[maxn],H[maxn];
int m,n;
char s[maxn]; int cmp(const int& a,const int& b) {
return hash[a]<hash[b] || (hash[a]==hash[b] && a<b);
}
int pos,rank[maxn];
bool can(int L) {
pos=-;
for(int i=;i<n-L+;i++) hash[i]=H[i]-H[i+L]*xp[L],rank[i]=i;
sort(rank,rank+n-L+,cmp);
int cnt=;
for(int i=;i<n-L+;i++) {
if(!i || hash[rank[i]]!=hash[rank[i-]]) cnt=;
if(++cnt>=m) pos=max(pos,rank[i]);
}
return pos>=;
} int main() {
//freopen("in.in","r",stdin);
//freopen("outr.out","w",stdout);
while(scanf("%d",&m)== && m) {
scanf("%s",s);
n=strlen(s); H[n]=,xp[]=;
for(int i=n-;i>=;i--) H[i]=H[i+]*x+s[i]-'a';
for(int i=;i<=n;i++) xp[i]=xp[i-]*x; if(!can()) printf("none\n");
else {
int L=,R=n+;
while(L<R) {
int M=L+(R-L+)/;
if(can(M)) L=M; else R=M-;
}
can(L);
printf("%d %d\n",L,pos);
}
}
return ;
}

hash

UVALive4513 Stammering Aliens(哈希法,后缀数组)的更多相关文章

  1. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  2. UVA 12206 - Stammering Aliens(后缀数组)

    UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组.搞出height数组后,利用二分去查找就可以 这 ...

  3. Uva12206 Stammering Aliens 后缀数组&&Hash

    Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...

  4. UVALive - 4513 Stammering Aliens ——(hash+二分 || 后缀数组加二分)

    题意:找一个出现了m次的最长子串,以及这时的最右的位置. hash的话代码还是比较好写的,,但是时间比SA多很多.. #include <stdio.h> #include <alg ...

  5. Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens

    题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...

  6. HDU4080Stammering Aliens(后缀数组+二分)

    However, all efforts to decode their messages have failed so far because, as luck would have it, the ...

  7. Stammering Aliens

    Stammering Aliens Time Limit: 2000MS   Memory Limit: 65536K       Description Dr. Ellie Arroway has ...

  8. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  9. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

随机推荐

  1. CSS3新增Hsl、Hsla、Rgba色彩模式以及透明属性(转)

    CSS2中色彩模式只有RGB色彩模式(RGB即RED.Green.BLue)和十六进制(Hex)模式,为了能支持 透明opacity 的Alpha值,CSS3又增加了RGBA色彩模式(RGBA即RED ...

  2. 浅谈Android系统的图标设计规范

    http://homepage.yesky.com/89/11620089.shtml 目前移动平台的竞争日益激烈,友好的用户界面可以帮助提高用户体验满意度,图标Icon是用户界面中一个重要的组成部分 ...

  3. ASP.NET 导入EXCEL文档

    鉴于教务一般都是手动输入学生信息,在未了解本校数据库的客观情况之下,我们准备设计一个导入excel文档中学生信息如数据库的功能.结合网上各类大牛的综合版本出炉.. 首先具体的实现思想如下: 1.先使用 ...

  4. JQuery zoom插件学习

    jquery zoom是一款图片放大插件,经常用在商城商品页面里. 使用JQuery zoom插件,除了需要引入JQuery.js外,还要引入JQuery.zoom.js文件及jqzoom.css文件 ...

  5. php基础知识【oop/mvc/orm/aop】

    OOP 面向对象编程是一种计算机编程架构.OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成.OOP 达到了软件工程的三个主要目标:重用性.灵活性和扩展性.为了实现整体运 ...

  6. 知识库总结mysql常用cmd命令

    打开命令目录 打开D盘mysql目录 d: cd D:\Ampps\mysql\bin 常用操作 将mysql目录下bin目录中的mysql.exe放到C:\WINDOWS下,可以执行以下命令 连接: ...

  7. Python 的“+”和append在添加字符串时候的区别

    对于一个空的Python列表,往后添加内容有很多种,其中两种一个是用“+”直接添加内容,另外一种是Listname.append(x)来添加内容 其中,如果处理字符串 在使用“+”的时候,会将字符串拆 ...

  8. [r]Seven habits of effective text editing

    Seven habits of effective text editing(via) Bram Moolenaar November 2000 If you spend a lot of time ...

  9. POJ 1321-棋盘问题(DFS 递归)

    POJ 1321-棋盘问题 K - DFS Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I6 ...

  10. 【转】web开发需要知道的事情

    在StackExchange上有人问了这样一个问题:What should every programmer know about web development?(关于Web开发,什么是所有程序员需 ...