UVALive4513 Stammering Aliens(哈希法,后缀数组)

时间:2022-09-28 22:31:07

题目链接: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(二分 &plus; 后缀数组)

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

  2. UVA 12206 - Stammering Aliens&lpar;后缀数组&rpar;

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

  3. Uva12206 Stammering Aliens 后缀数组&amp&semi;&amp&semi;Hash

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

  4. UVALive - 4513 Stammering Aliens ——(hash&plus;二分 &vert;&vert; 后缀数组加二分)

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

  5. Hash&lpar;LCP&rpar; &vert;&vert; 后缀数组 LA 4513 Stammering Aliens

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

  6. HDU4080Stammering Aliens(后缀数组&plus;二分)

    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&colon; &lbrack;Noi2015&rsqb;品酒大会 &lbrack;后缀数组 带权并查集&rsqb;

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

随机推荐

  1. get&lowbar;locked&lowbar;objects&lowbar;rpt&period;sql

    在metalink上看到一个脚本(get_locked_objects_rpt.sql),非常不错,如下所示 /*------------------------------------------- ...

  2. iOS-数据持久化基础-JSON与XML数据解析

    解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...

  3. &lbrack;转&rsqb;jQuery Popup Login and Contact Form

    本文转自:http://www.formget.com/jquery-popup-form/ Pop up forms are the smart way to present your site. ...

  4. vs2013 IHttpActionResult NotFund Ok (WebAPI)

    vs2013  IHttpActionResult NotFund Ok   使用ASP.NET Web API构造基于restful风格web services,IHttpActionResult是 ...

  5. java BigInteger源码学习

    转载自http://www.hollischuang.com/archives/176 在java中,有很多基本数据类型我们可以直接使用,比如用于表示浮点型的float.double,用于表示字符型的 ...

  6. SQLServer导出数据表结构

    SELECT (case when a.colorder=1 then d.name else '' end)表名, a.colorder 字段序号, a.name 字段名, (case when C ...

  7. 规约模式(Specification Pattern)

    一.引言 最近在看一个项目的源码时(DDD),对里面的一些设计思想和设计思路有了一些疑问.当看到(Repository层)中使用了 spec.SatisfiedBy() 时,感觉有点懵.于是在项目中搜 ...

  8. activiti监听器使用

    分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519) activiti使用的时候,通常需要跟业务紧密的结合在一起,有些业 ...

  9. coursera国际法笔记 持续更新

    LECTURE ONE International crime court(ICC) came into being after the Second World War. The Nuremberg ...

  10. less中使用calc

    css3中可以使用calc()来实现自适应布局 例如:width:“calc(100%  - 25px)” width: calc(expression); ==> expression是一个表 ...