题目链接:https://cn.vjudge.net/problem/POJ-1743

题意

给一串整数,问最长不可重叠最长重复子串有多长

注意这里匹配的意思是匹配串的所有元素可以减去或者加上某个值

例: 34 30 26 22 18 82 78 74 70 66

后5个整数的串可以匹配前5个数

思路

LCP问题(最长公共前缀)

两个思路

  1. 后缀数组

    对height数组二分长度,找到height大于len且两字符串起点差值大于len的情况下,len最大值
  2. 哈希+二分

    二分长度,哈希值比较字符串找到当前len下符合要求子串即可

这题我用的第二个思路

首先差分一下,然后二分长度,用哈希的方法比较两个字符串O(1)

总复杂度O(nlog)(初始化O(n)+二分O(1nlogn))

刚从蓝书看来的,然而本题对hash表要求很高(能够处理unsigned long long大小键值)

那个简洁的HashMap还是要改改

具体写下好了

首先构建一个H数组,具体的

\[H[i]= \sum S[i] base^{n-i-1}
\]

对一个以i为起点,len为长度的字符串,他的Hash值:

\[Hash(i, len)=H[i]-H[i+len] base^len
\]

然后O(n)的字符串比较复杂度降到O(1)

这里可能会撞hash,所以保险一点咱还得再直接判断是否相同

提交过程

WA*n
TLE*n
AC

代码

#include <cstdio>
#include <cstring>
const int maxn=2e4+20;
const int HASH = 10007;
const int MAXN = 20010;
const unsigned long long hashBase=13331;
struct HASHMAP{
int head[HASH],next[MAXN],size;
unsigned long long state[MAXN];
int f[MAXN];
void init(){
size = 0;
memset(head,-1,sizeof(head));
} int insert(unsigned long long val,int _id){
int h = val%HASH;
for(int i = head[h]; i != -1;i = next[i])
if(val == state[i]) return f[i];
f[size] = _id;
state[size] = val;
next[size] = head[h];
head[h] = size++;
return f[size-1];
}
}hash;
unsigned long long hashBasePow[maxn], H[maxn];
int str[maxn], n; bool judge(int len){
hash.init();// hash.clear();
for(int i=0; i<n-len; i++){
unsigned long long key=H[i]-H[i+len]*hashBasePow[len];
if (hash.insert(key, i)<i-len) return true;
}return false;
} int solve(void){
int ans=0;
int l=4, r=n-1;
while(l<=r){
int mid=l+(r-l)/2;
if(judge(mid)) ans=mid, l=mid+1;
else r=mid-1;
}
if(ans<4) ans=-1;
return ans+1;
} int main(){
hashBasePow[0]=1;
for(int i=1; i<maxn; i++)
hashBasePow[i]=hashBasePow[i-1]*hashBase;
while(scanf("%d", &n)==1 && n){
for (int i=0; i<n; i++) scanf("%d", &str[i]);
for (int i=0; i<n-1; i++) str[i]-=str[i+1]; H[n-1]=str[n-1];
for (int i=n-2; i>=0; i--)
H[i]=H[i+1]*hashBase+str[i];
printf("%d\n", solve());
}
return 0;
}
Time Memory Length Lang Submitted
547ms 1080kB 1557 G++ 2018-08-03 15:26:17

POJ-1743 Musical Theme 字符串问题 不重叠最长重复子串的更多相关文章

  1. POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串

    二分长度k 长度大于等于k的分成一组 每组sa最大的和最小的距离大于k 说明可行 #include <cstdio> #include <cstring> #include & ...

  2. [Poj1743] [后缀数组论文例题] Musical Theme [后缀数组不可重叠最长重复子串]

    利用后缀数组,先对读入整数处理str[i]=str[i+1]-str[i]+90这样可以避免负数,计算Height数组,二分答案,如果某处H<lim则将H数组分开,最终分成若干块,判断每块中是否 ...

  3. POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)

    永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...

  4. POJ 1743 Musical Theme(不可重叠最长重复子串)

    题目链接:http://poj.org/problem?id=1743 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一 ...

  5. poj 1743 Musical Theme(最长重复子串 后缀数组)

    poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...

  6. Poj 1743 Musical Theme (后缀数组+二分)

    题目链接: Poj  1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...

  7. POJ - 1743 Musical Theme (后缀数组)

    题目链接:POJ - 1743   (不可重叠最长子串) 题意:有N(1<=N<=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的子串,它需要 ...

  8. POJ 1743 Musical Theme(后缀数组)

    题意:有n个数值,算出相邻两个值的差值,此时有n-1个值的序列,把这序列当做字符串的话,求最长重复子串,且这两个子串不能重叠. 分析:后缀数组解决.先二分答案,把题目变成判定性问题:判断是否存在两个长 ...

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

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

随机推荐

  1. 扩大缩小Linux物理分区大小

    由于产品在不同的标段,设备硬盘也不同, 有些500G,有些320G有些200G,开始在大硬盘上做的配置,想把自己定制好的Linux克隆到小硬盘上,再生龙会纠结空间大小的问题, 因此需要做一些分区的改变 ...

  2. sqlserver中计算结果保留小数

    经常要保留小数,在程序中计算太麻烦了,还要转换操作.直接在数据库中操作来得方便. 把数据类型定义成decimal/numeric类型,小数位看需要随意设,除数与被除数必须要有一个为decimal/nu ...

  3. BZOJ 4016 [FJOI2014]最短路径树问题 (贪心+点分治)

    题目大意:略 传送门 硬是把两个题拼到了一起= = $dijkstra$搜出单源最短路,然后$dfs$建树,如果$dis_{v}=dis_{u}+e.val$,说明这条边在最短路图内,然后像$NOIP ...

  4. HDU 5421 Victor and String (回文自动机)

    题目大意:让你维护一个字符串,支持在开头结尾插入字符,以及查询本质不同的回文串数量以及回文串总数量 开头结尾都维护一个$last$指针,如果插入新字符后,整个串是一个回文串,就把另一个$last$赋值 ...

  5. mkl安装与使用

    mkl安装教程 1.下载 首先到该网站下载压缩包,需要注册 2.安装 首先解压缩 tar -zxvf l_mkl_2019.0.117.tgz 进入目录进行安装 cd l_mkl_2019.0.117 ...

  6. python在不同情况下写入csv文件

    情况一(解法一):将列表存储为csv文件.列表的每一项代表csv文件的一行. 列表中的每一项包含多个属性.list=[[属性1,属性2,属性3,……],[属性1,属性2,属性3,……],[属性1,属性 ...

  7. 异构关系数据库(MySql与Oracle)之间的数据类型转换参考

    一.MySQL到Oracle的数据类型的转变: 编号 MySQL ToOracle Oracle 1 GEOMETRY BLOB BLOB 2 GEOMETRYCOLLECTION BLOB BLOB ...

  8. java类的属性

    类的嵌套!!!!!!!!!! 首先我们创建一个学生卡卡号的一个类,这个类有两个属性,校园卡号和银行卡号 package cuteSnow; public class StudentCard { pub ...

  9. angular-HTML DOM

    ng-disabled用法 <div ng-app="" ng-init="mySwitch=true"> <p> <button ...

  10. iOS 手势识别器概述

    手势识别器 iOS 手势识别器(UIGestureRecognizer) 点击手势(UITapGestureRecognizer) 滑动手势(UISwipeGestureRecognizer) 旋转手 ...