Stammering Aliens
| Time Limit: 2000MS | Memory Limit: 65536K | |
Description
Thus, the message contains possibly overlapping repetitions of the same words over and over again. As a result, Ellie turns to you, S.R. Hadden, for help in identifying the gist of the message.
Given an integer m, and a string s, representing the message, your task is to find the longest substring of s that appears at least m times. For example, in the message baaaababababbababbab, the length-5 word babab is contained 3 times, namely at positions 5, 7 and 12 (where indices start at zero). No substring appearing 3 or more times is longer (see the first example from the sample input). On the other hand, no substring appears 11 times or more (see example 2). In case there are several solutions, the substring with the rightmost occurrence is preferred (see example 3).
Input
Output
Sample Input
3
baaaababababbababbab
11
baaaababababbababbab
3
cccccc
0
Sample Output
5 12
none
4 2
分析:求出现至少m次的最长字符子串及最大位置;
后缀数组+set;(二分hash)
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, ls[rt]
#define Rson mid+1, R, rs[rt]
#define sys system("pause")
#define freopen freopen("in.txt","r",stdin)
const int maxn=4e4+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
inline ll read()
{
ll x=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,k,t,cntA[maxn],cntB[maxn],sa[maxn],lev[maxn],height[maxn],A[maxn],B[maxn],tsa[maxn];
char ch[maxn];
void solve()
{
for (int i = ; i < ; i ++) cntA[i] = ;
for (int i = ; i <= n; i ++) cntA[ch[i]] ++;
for (int i = ; i < ; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (ch[sa[i]] != ch[sa[i - ]]) lev[sa[i]] ++;
}
for (int l = ; lev[sa[n]] < n; l <<= )
{
for (int i = ; i <= n; i ++) cntA[i] = ;
for (int i = ; i <= n; i ++) cntB[i] = ;
for (int i = ; i <= n; i ++)
{
cntA[A[i] = lev[i]] ++;
cntB[B[i] = (i + l <= n) ? lev[i + l] : ] ++;
}
for (int i = ; i <= n; i ++) cntB[i] += cntB[i - ];
for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
for (int i = ; i <= n; i ++) cntA[i] += cntA[i - ];
for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
lev[sa[]] = ;
for (int i = ; i <= n; i ++)
{
lev[sa[i]] = lev[sa[i - ]];
if (A[sa[i]] != A[sa[i - ]] || B[sa[i]] != B[sa[i - ]]) lev[sa[i]] ++;
}
}
for (int i = , j = ; i <= n; i ++)
{
if (j) j --;
while (ch[i + j] == ch[sa[lev[i] - ] + j]) j ++;
height[lev[i]] = j;
}
}
multiset<int>p;
set<int>q;
int main()
{
int i,j;
while(~scanf("%d",&m)&&m)
{
scanf("%s",ch+);
n=strlen(ch+);
if(m==)
{
printf("%d %d\n",n,);
continue;
}
solve();
p.clear(),q.clear();
rep(i,,m-)p.insert(height[i]),q.insert(sa[i]);
int ans=,pos=-;
rep(i,m,n)
{
p.erase(p.lower_bound(height[i-m+]));
p.insert(height[i]);
q.insert(sa[i]);
if(ans<=*p.begin())
{
auto x=q.end();
x--;
if(ans<*p.begin()||*x->pos)pos=*x-;
ans=*p.begin();
}
q.erase(sa[i-m+]);
}
if(ans)printf("%d %d\n",ans,pos);
else puts("none");
}
//system("Pause");
return ;
}
Stammering Aliens的更多相关文章
- UVA 12206 - Stammering Aliens(后缀数组)
UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组.搞出height数组后,利用二分去查找就可以 这 ...
- Uva12206 Stammering Aliens 后缀数组&&Hash
Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...
- HDU4080 Stammering Aliens(二分 + 后缀数组)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...
- UVALive - 4513 Stammering Aliens ——(hash+二分 || 后缀数组加二分)
题意:找一个出现了m次的最长子串,以及这时的最右的位置. hash的话代码还是比较好写的,,但是时间比SA多很多.. #include <stdio.h> #include <alg ...
- Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens
题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...
- UVa 12206 (字符串哈希) Stammering Aliens
体验了一把字符串Hash的做法,感觉Hash这种人品算法好神奇. 也许这道题的正解是后缀数组,但Hash做法的优势就是编码复杂度大大降低. #include <cstdio> #inclu ...
- 【HDOJ】4080 Stammering Aliens
1. 题目描述给定一个长为$n \in [1, 4000]$的字符串,求其中长度最长的子串,并且该子串在原串中出现至少$m$次,并求最右起始位置. 2. 基本思路两种方法:二分+后缀数组,或者二分+哈 ...
- uvalive 4513 Stammering Aliens
题意:给你一个串,问期中至少出现m次的最长子串及其起始位置的坐标. 思路:hash+LCP+二分答案 #include<cstdio> #include<cstring> #i ...
- uva 12206 - Stammering Aliens
基于hash的LCP算法: #include<cstdio> #include<cstring> #include<algorithm> #define maxn ...
随机推荐
- 【Sort】多种排序
这篇文章包含了插入排序,希尔排序,堆排序,归并排序和快速排序,是前几篇文章的集合. 一共包括三个文件 sort.h sort.cpp main.cpp 1.main.cpp #include < ...
- 浙大pat1019题解
1019. General Palindromic Number (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN ...
- 安卓请求服务器js文件下载到本地,版本号就下载
<?phpreturn array('CJ_V' => 'v0.15',) <script src="/js/reserve.js?<?=C('CJ_V')?> ...
- Android 切横竖屏时走的生命周期方法?222
第一种情况: 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次 第二种情况: 设置Activity的androi ...
- MySQL(3)-索引
一.索引类型 在MySQL中,存储引擎使用索引,首先在索引中找到对应值,然后根据匹配的索引记录中找到对应的行. 无论是多么复杂的ORM工具,在精妙和复杂的索引面前都是"浮云".这里 ...
- HDU 1242 Rescue(BFS),ZOJ 1649
题目链接 ZOJ链接 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The ...
- css3的特效拓展...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Openjudge-计算概论(A)-能被3,5,7整除的数
描述: 输入一个整数,判断它能否被3,5,7整除,并输出以下信息:1.能同时被3,5,7整除(直接输出3 5 7,每个数中间一个空格):2.能被其中两个数整除(输出两个数,小的在前,大的在后.例如:3 ...
- Ubuntu14.04下手动建立快捷方式
先在桌面创建一个文件:文件内容如下 [Desktop Entry]Encoding=UTF-8Name=eclipseComment=eclipse ideExec=/home/mars/eclips ...
- Sql Server 和 Access 数据库在书写sql语句时的语法差异
sql:datediff(d,eff_time,getdate()) access: datediff('d',eff_time,getdate())