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. ios相关配置

    Deployment Target,它控制着运行应用需要的最低操作系统版本.

  2. ajax(form)图片上传(spring)

    第一步:spring-web.xml <!--配置上传下载--> <bean id="multipartResolver" class="org.spr ...

  3. 前端JavaScript之BOM

    BOM:浏览器对象模型,操作浏览器部分功能的API.比如让浏览器自动滚动. 1.window对象 所有浏览器都支持 window 对象.概念上讲.一个html文档对应一个window对象.功能上讲: ...

  4. Java学习过程中的收获

    1. String <--> Date 这种转换要用到java.text.SimpleDateFormat类 字符串转换成日期类型: 方法1: 也是最简单的方法 Date date=new ...

  5. 牛客小白月赛2 E 是是非非 【尼姆博弈】

    链接:https://www.nowcoder.com/acm/contest/86/E来源:牛客网 题目描述 坎为水,险阳失道,渊深不测:离为火,依附团结,光明绚丽. 坎卦:水洊至,习坎:君子以常德 ...

  6. MySQL主从复制读写分离如何提高从库性能-实战

    在做主从读写分离时候,需要注意主从的一些不同参数设置,来提高从库的性能,提高应用读取数据的速度,这样做很有必要的. 做读写分离复制主从参数不同设置如下(需要根据自己应用实际情况来设置): parmet ...

  7. LInux操作随手笔记

    一.find 的用法 实例 find / -name test.txt 就可以找到这个文件的路径(如果存在). 二.学用vi编辑器,学用rz往linux服务器上面上传文件 linux中rz 和 sz ...

  8. swoole学习(一)----linux安装swoole

    1.下载swoole 登录swoole官网 https://www.swoole.com/ 点击下载,找到github或者其他链接下载下来 放到虚拟机上. 也可以使用虚拟机下载 2.登录虚拟机 推荐使 ...

  9. php扩展开发-INI配置

    php.ini文件是用来保存各项扩展配置的文件,每个扩展都或多或少需要有一个定制化的配置,ini文件是一个很好的保存配置的方式,我们来看下怎么在自己的扩展里,使用到ini的配置功能 //创建ini的配 ...

  10. C语言真正的编译过程(4个步骤~~预编译,编译,汇编,连接)

    转载自:https://www.cnblogs.com/wuyouxiaocai/p/5701088.html#commentform 说实话,很多人做了很久的C/C++,也用了很多IDE,但是对于可 ...