3043: 取个标题好难 

Time Limit(Common/Java):6000MS/18000MS     Memory Limit:65536KByte
Total Submit: 17            Accepted:4

Description

你是否经常在写完文章之后为文章取一个合适的标题而苦恼?这里提供一个很有趣的方法。
首先,标题应该概括文章的内容。为了简单起见,如果一个短语在文章中不重叠地出现了至少k次,那么这个短语就可以作为标题。例如,”dadadad”中,短语”dad” 不重叠地出现了两次,而不是三次。
其次,标题越长越好。长标题才能吸引眼球。
最后,这件事应该让计算机来做比较省事。
所以,请编写一个程序,根据给定的k和一段文章,给这篇文章取个标题。

Input

输入包括多组数据。
每组数据第一行为整数k,第二行为一个字符串表示文章内容,为了简化问题,字符串仅含小写字母。字符串长度不超过10000。
输入数据以k=0结束。

Output

对每组数据输出最长的标题长度,如果找不到符合要求的标题,则输出0。

Sample Input

3
abababa
1
apple
4
abababa
5
abababa
0

Sample Output

2
5
1
0

最长的出现次数>=k的不重复子串长度,这个题目明显可以hash,然后在二分长度,排序的时候将位置也标记下,最后判断下就可以了

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ulint;
#define maxn 23333
const ulint x=;
int M;
char in[maxn];
ulint has[maxn];
int pos[maxn];
int id[maxn];
ulint xp[maxn];
ulint H[maxn];
bool cmp(int a,int b)
{
return has[a]<has[b]||has[a]==has[b]&&a<b;
}
bool check(int mid,int n)
{
pos[mid]=;
id[]=;
for(int i=; i+mid-<n; i++)//就算每一段的hash值
id[i]=i,has[i]=H[i]-H[i+mid]*xp[mid];
sort(id,id+n-mid+,cmp);//按hash值排序
int cnt=;
bool ret=;
int tmp=id[];
for(int i=; i<=n-mid; i++)
if(has[id[i]]==has[id[i-]])
{
if(id[i]-tmp>=mid)
cnt++,tmp=id[i];
if(cnt>=M)
pos[mid]=max(pos[mid],tmp),ret=;
}
else
cnt=,tmp=id[i];
return ret;
}
int main()
{
xp[]=;
for(int i=; i<maxn; i++)//预处理x次幂项
xp[i]=xp[i-]*x;
while(scanf("%d",&M),M)
{
scanf("%s",in);
int n=strlen(in);
if(M==)
{
printf("%d\n",n);
continue;
}
H[n]=;
for(int i=n-; i >= ; i--)//预处理H[i]=s[i]+s[i+1]*x+...+s[n]*x^(n-i)
H[i]=H[i+]*x+(in[i]-'a');
int L=,R=n,mid,len=;
while(L<=R)
{
mid=(L+R)>>;
if(check(mid,n))
{
len=mid;
L=mid+;
}
else
R=mid-;
}
if(len==)
printf("0\n");
else
printf("%d\n",len);
}
return ;
}

然后也可以后缀数组,我们之前那个题允许重复,直接判断height即可,这个题目要保存sa[i],然后排序判断是否重复

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <set>
#define dbg(x) std::cout<<#x<<" = "<< (x)<< "\n"
#define maxn 20005
int wa[maxn],wb[maxn],wv[maxn],ws[maxn],m;
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void getsa(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[x[i]=r[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[x[i]]]=i;
for(j=,p=; p<n; j*=,m=p)
{
for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[wv[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
int rank[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=; i<=n; i++) rank[sa[i]]=i;
for(i=; i<n; height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-]; r[i+k]==r[j+k]; k++);
}
int a[maxn];
int check(int *sa,int n,int k)
{
int i,cnt=;
a[]=sa[];
for(i=; i<=n; i++)
{
if(height[i]>=k)
{
a[cnt++]=sa[i];
}
else
{
if(cnt>=m)
{
std::sort(a,a+cnt);
int x=a[],tot=cnt;
for(int i=; i<tot; i++)
{
if(a[i]-x<k)cnt--;
else x=a[i];
}
if(cnt>=m)return ;
}
cnt=,a[]=sa[i];
}
}
std::sort(a,a+cnt);
int x=a[],tot=cnt;
for(int i=; i<tot; i++)
{
if(a[i]-x<k)cnt--;
else x=a[i];
}
if(cnt>=m)return ;
return ;
}
int r[maxn],sa[maxn];
char str[maxn];
int main()
{
//freopen("test.in","r",stdin);
while(scanf("%d",&m),m)
{
scanf("%s",str);
int n=strlen(str);
if(m==)
{
printf("%d\n",n);
continue;
}
for(int i=; i<n; i++)r[i]=str[i];
r[n]=;
getsa(r,sa,n+,);
calheight(r,sa,n);
int L=,R=n,mi,len=;
while(L<=R)
{
mi=(L+R)>>;
if(check(sa,n,mi))L=mi+,len=mi;
else R=mi-;
}
printf("%d\n",len);
}
return ;
}

TZOJ3043: 取个标题好难 最长的出现次数>=k的不重复子串长度的更多相关文章

  1. Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22499   Accepted: 7679 De ...

  2. 最长不重复子串长度,时间复杂度O(n),空间复杂度O(n),Python实现

    def lengthOfLongestSubstring(s): res = 0 d = {} tmp = 0 start = 0 for i in range(len(s)): if s[i] in ...

  3. LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)

    题目链接 Given a string, find the length of the longest substring without repeating characters. For exam ...

  4. POJ 3261 Milk Patterns 可重复k次的最长重复子串

    Milk PatternsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3261 Description ...

  5. Longest Substring Without Repeating Characters 最长不重复子串

    只遍历一次字符串即可求出最长不重复子串的长度. int lengthOfLongestSubstring(string s) { vector<,-); //记录字符上一次出现的位置,ASCII ...

  6. poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14874   Accepted: 5118 De ...

  7. [Jobdu] 题目1530:最长不重复子串

    题目描述: 最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的. 输入: 输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c... ...

  8. 【poj1743-Musical Theme】不可重叠最长重复子串-后缀数组

    http://poj.org/problem?id=1743 这题是一道后缀数组的经典例题:求不可重叠最长重复子串. 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲 ...

  9. 九度oj 题目1530:最长不重复子串

    题目描述: 最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的. 输入: 输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c... ...

随机推荐

  1. Git笔记(pull/push)

    一.从远程服务器上获取分支 git pull <远程主机名> <远程分支>:<本地分支> 例如 git pull origin master:loacal_bran ...

  2. C#继承的多态性

    C#继承的多态性 当一个类A派生出新类B时,这个基类A在新类B中可以表现为不同的类型:用作它自己的类型.基类型,或者在实现接口时用作接口类型,我们将这种情况称为多态性. C#中的每种类型都是多态性的, ...

  3. img适配问题解决方法

    将img放到background中,将background-size设置为100%:只需要适配背景为img的元素的宽和高即可.

  4. Java 单词 day seven

    Constructor Constructor Constructor Constructor Constructor Constructor Constructor Constructor Cons ...

  5. jquery操作DOM 元素(3)

    .detach() 从DOM 中去掉所匹配的元素. .detach([selector]) selector 一个选择表达式将需要移除的从匹配的元素中过滤出来. $("p").de ...

  6. spring-bean(xml方式DI)

    三种属性注入方式 构造函数注入 1.在Bean实体中写入构造函数(带参构造) 2. <bean id=”该bean的名称” class=”注入的bean的全路径”> <constru ...

  7. vue本人常用插件汇总(常更新)

    1. 移动端UI插件 mint-ui http://mint-ui.github.io/#!/zh-cn 2.vue状态管理vuex,持久化插件:vuex-persist https://github ...

  8. pyhton——logging日志模块的学习

    https://www.cnblogs.com/yyds/p/6901864.html 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模 ...

  9. 解答室内定位技术新方向:蓝牙AoA定位,值得了解 ——概念了解

    转载搜狐 室内定位一直被炒的非常火的黑科技,也是近年资本追逐的热点,市场上一直有众多宣称可以做到厘米级,米级精度定位的公司,但问题很多,无法大规模商用.近些年有很多人尝试使用蓝牙beacon方式做定位 ...

  10. [CodeForces954D]Fight Against Traffic(最短路)

    Description 题目链接 Solution 从起点和终点分别做一次最短路并记录结果 枚举每一条可能的边判断 Code #include <cstdio> #include < ...