POJ-1743 Musical Theme (后缀数组 不重叠最长重复子串)
来源:互联网 发布:人工智能类似电影 编辑:程序博客网 时间:2024/05/20 05:10
题目:
http://poj.org/problem?id=1743题意:
给出一段音符大小,求其中重复出现的最长的子串,如果一个串中的所有音符同时增大或者缩小一个数能够变成另一个串也算相同。
要求两个串不重叠且至少长度为5.
思路:
标准后缀数组的模版题,因为可以通过加减一个数达到满足情况,所以不能直接用原始数组,要求出所有相邻元素之间的差值,然后差值数组作为seq,求出后缀数组。其中如果有长度为 t 子串相同,则代表原数组中一定有大小为t+1的子串相同。
所以只要求出后缀数组然后二分枚举长度res,利用后缀数组的height数组可以将所有前缀有大于等于res个数相同的子串分在一组,判断每组中是否有两个串的起始距离大于res也就是不重叠就行了。因为是差值数组所以二者的起始距离一定要大于res不能等于。
代码:
#include <bits/stdc++.h>#define N 20005using namespace std;int n,m,sum,res,flag,k;int seq[N], sa[N], ranks[N], height[N];int wwa[N], wwb[N], wws[N], wwv[N];bool cmp(int r[], int a, int b, int l){ return r[a] == r[b] && r[a+l] == r[b+l];}void da(int r[],int n, int m){ int i, j, p, *x = wwa, *y = wwb; for (i = 0; i < m; ++i) wws[i] = 0; for (i = 0; i < n; ++i) wws[x[i]=r[i]]++; for (i = 1; i < m; ++i) wws[i] += wws[i-1]; for (i = n-1; i >= 0; --i) sa[--wws[x[i]]] = i; for (j = 1, p = 1; p < n; j *= 2, m = p) { for (p = 0, i = n - j; i < n; ++i) y[p++] = i; for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; for (i = 0; i < n; ++i) wwv[i] = x[y[i]]; for (i = 0; i < m; ++i) wws[i] = 0; for (i = 0; i < n; ++i) wws[wwv[i]]++; for (i = 1; i < m; ++i) wws[i] += wws[i-1]; for (i = n-1; i >= 0; --i) sa[--wws[wwv[i]]] = y[i]; for (swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++; }}void calheight(int r[], int n){ int i, j, k = 0; for (i = 1; i <= n; ++i) ranks[sa[i]] = i; for (i = 0; i < n; height[ranks[i++]] = k) for (k?k--:0, j = sa[ranks[i]-1]; r[i+k] == r[j+k]; k++);}void solve(){ //初始序0~n,最大值小于m。 seq[n]=0; da(seq,n+1,m); calheight(seq,n);}int main(){ int i,j,kk,cas,T,t,x,y,z; while(scanf("%d",&n)!=EOF&&n) { for(i=0;i<n;i++) scanf("%d",&seq[i]); for(i=1;i<n;i++) seq[i-1]=seq[i]-seq[i-1]+88; n--;m=200; solve(); x=4;y=n/2;res=-1; while(x<=y) { z=(x+y)/2; flag=false; for(i=2;i<=n&&!flag;i++) { int l,r;l=r=sa[i-1]; while(height[i]>=z)l=min(l,sa[i]),r=max(r,sa[i]),i++; if(r-l>z)flag=true; } if(flag) x=z+1,res=z; else y=z-1; } printf("%d\n",res+1); } return 0;}
0 0
- poj 1743 Musical Theme(最长不重叠重复子串 后缀数组+二分)
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- POJ-1743 Musical Theme (后缀数组 不重叠最长重复子串)
- poj 1743 Musical Theme 【后缀数组 最长不重叠重复子串】
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- POJ 173 Musical Theme 后缀数组 + 最长不重叠重复子串
- POJ 题目1743 Musical Theme(后缀数组,求一个串中最长不重叠重复子串)
- POJ 1743 Musical Theme(后缀数组求不可重叠最长重复子串)
- Poj 1743 Musical Theme (后缀数组 不可重叠最长重复子串)
- poj 1743 Musical Theme (后缀数组 不可重叠最长重复子串)
- poj 1743 Musical Theme(不可重叠的最长重复子串,后缀数组)
- POJ 1743 Musical Theme ( 后缀数组 + 二分 不可重叠最长重复子串 )
- POJ 1743 Musical Theme (后缀数组加二分求不可重叠最长重复子串)
- POJ - 1743 Musical Theme (后缀数组求不可重叠最长重复子串)
- POJ 1743 Musical Theme 后缀数组 不可重叠最长重复子串
- POJ - 1743 - Musical Theme(后缀数组 - 不可重叠最长重复子串)
- POJ 1743 Musical Theme(后缀数组[不可重叠最长重复子串])
- POJ 1743 Musical Theme(不可重叠最长重复子串 后缀数组)
- 物体的刚体组件Rigidbody component 详解
- Java多线程(五)——Volatile关键字
- Spring 使用原生的jdbc或整合ORM操作数据库的模板编程
- 关于静默安装apk
- java exception test
- POJ-1743 Musical Theme (后缀数组 不重叠最长重复子串)
- Linux makefile 教程 非常详细,且易懂
- socket服务需要注意这两个头文件
- Android 自定义View实现动态炫酷按钮
- SVM训练样本方法总结(用于目标识别)
- Oracle数据库数据迁移到MySQL数据库之connect by 问题
- unity3d,android平台下,高德地图定位
- String s1 = new String("abc"); String s2 = ("abc");
- 数据结构之排序