poj 1743 二分答案+后缀数组 求不重叠的最长重复子串
题意:给出一串序列,求最长的theme长度
(theme:完全重叠的子序列,如1 2 3和1 2 3 or 子序列中每个元素对应的差相等,如1 2 3和7 8 9)
要是没有差相等这个条件那就好办多了,直接裸题。
一开始想了个2B方法,后来发现真心2B啊蛤蛤蛤
for i= to do
{
for j= to length
{
r2[j]=r[j]+i;
if (r2[j]>) r2[i]-=;
}
把新序列r2连接到原序列r的后面
process[r+r2]
.....
求for i=->88中得到的最大答案
}
正解:http://bbezxcy.iteye.com/blog/1407395
对原序列相邻两元素作差就行了= =
比如:序列8 8 8 15 24 3 3 3
作差得到0 0 7 9 -21 0 0
对新序列再求最长不重叠重复子串,得到的结果+1,就是原序列的最长不重叠重复子串
求最长不重叠重复子串:参考IOI2009论文
Code:
#include "stdio.h"
#include "string.h"
#define maxn 20010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
int rank[maxn],height[maxn];
int r[maxn],sa[maxn],ans[maxn];
int n; int 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 *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++;
}
return;
} 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++);
return;
} bool calc(int x)
{
int nm=;
for (int i=;i<=n;i++)
if (height[i]<x)
{
nm++;
ans[nm]=i;
}
nm++;
ans[nm]=n+;
for (int i=;i<nm;i++)
{
int tl=ans[i],tr=ans[i+]-;
int tn=maxn,tx=;
for (int j=tl;j<=tr;j++)
{
if (tn>sa[j]) tn=sa[j];
if (tx<sa[j]) tx=sa[j];
}
if (tx-tn>=x) return true;
}
return false;
} //da(r,sa,n+1,128);
//calheight(r,sa,n);
int main()
{
// freopen("in.txt","r",stdin);
while (~scanf("%d",&n))
{
if (n!=)
{
memset(sa,,sizeof(sa));
memset(height,,sizeof(height));
memset(ans,,sizeof(ans)); for (int i=; i<n; i++)
scanf("%d",&r[i]);
r[n]=; // for (int i=0;i<=n;i++)
// printf("%d ",r[i]);
// printf("\n %d\n",n); for (int i=;i<n;i++)
r[i-]=r[i]-r[i-];
n--;
r[n]=; for (int i=;i<n;i++)
r[i]+=; // for (int i=0;i<=n;i++)
// printf("%d ",r[i]);
// printf("\n %d\n",n); da(r,sa,n+,);
calheight(r,sa,n); // for (int i=0; i<=n; i++)
// printf("%d %d\n",sa[i],height[i]);
// printf("\n"); int l=maxn,r=,res=;
for (int i=;i<=n;i++)
{
if (height[i]<l) l=height[i];
if (height[i]>r) r=height[i];
}
while (r>=l)
{
int mid=(l+r)/;
if (calc(mid))
{
l=mid+;
res=mid;
}
else
r=mid-;
}
res++;
if (res<) res=;
printf("%d\n",res);
}
}
return ;
}
本题出自USACO5.1 theme,据说是男人八题之一.....orz
poj 1743 二分答案+后缀数组 求不重叠的最长重复子串的更多相关文章
- poj 3261 二分答案+后缀数组 求至少出现k次的最长重复子序列
#include "stdio.h" #define maxn 20010 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int rank[ma ...
- poj 3261 Milk Patterns(后缀数组)(k次的最长重复子串)
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7938 Accepted: 3598 Cas ...
- POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)
Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...
- POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次
Milk Patterns Description Farmer John has noticed that the quality of milk given by his cows varie ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )
二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- Poj 1743 Musical Theme (后缀数组+二分)
题目链接: Poj 1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...
- POJ.1743.Musical Theme(后缀数组 倍增 二分 / 后缀自动机)
题目链接 \(Description\) 给定一段数字序列(Ai∈[1,88]),求最长的两个子序列满足: 1.长度至少为5 2.一个子序列可以通过全部加或减同一个数来变成另一个子序列 3.两个子序列 ...
随机推荐
- poj2407
欧拉函数裸题. 欧拉函数:在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目. 欧拉函数的定义: E(N)= ( 区间[1,N-1] 中与 N 互质的整数个数). 对于 积性函数 F ...
- poj1144
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12521 Accepted: 5760 Descript ...
- 18SpringMvc_在业务控制方法中收集数组参数
这篇文章我们要解决的问题的多选框选中,并批量删除. 比如:
- MVC4 WebAPI POST数据问题
api [HttpPost] public string PostAvartos(Test model) { if (model != null) { LoggerHelper.WriteInfo(m ...
- 一段后台C#查询SQL Server数据库代码
using System; using System.Data; using System.Collections.Generic; using System.Linq; using System.W ...
- C++哈弗曼编码
// haffman.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using name ...
- php基础07:流程控制
<?php //1.PHP foreach循环只适用于数组,并用于遍历数组中的每个键/值对. $colors = array("red","green", ...
- JAVA NIO是什么(zz)
JAVA NIO是什么? 1. 基本 概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系 ...
- C#中out和ref之间的区别
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...
- SVPullToRefresh 下拉刷新,上拉加载
https://github.com/Sephiroth87/ODRefreshControl 类似刷新控件,类似qq动画的那种刷新. 一.下载第三方库 https://github.com/samv ...