【BZOJ2946】[Poi2000]公共串

Description

       给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l        读入单词
l        计算最长公共子串的长度
l        输出结果

Input

文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。

Output

仅一行,一个整数,最长公共子串的长度。

Sample Input

3
abcb
bca
acbc

Sample Output

题解:把所有字符串连起来,中间用极小值隔开(极小值不能相同,用最大值也行),跑后缀数组,然后二分答案,如果能找出一段区间包括所有的单词,并且公共线坠长度≥答案,则答案可行

感觉几年没写后缀数组了,细节多得可以~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,num;
const int maxn=10100;
int r[maxn],ra[maxn],rb[maxn],sa[maxn],sb[maxn],st[maxn],rank[maxn],h[maxn],s[10],bel[maxn];
char str[maxn];
void work()
{
int i,j,k,*x=ra,*y=rb,p;
for(i=0;i<n;i++) st[x[i]=r[i]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[i]]]=i;
for(j=p=1;p<n;j<<=1,m=p)
{
for(i=n-j,p=0;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<m;i++) st[i]=0;
for(i=0;i<n;i++) st[x[y[i]]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[y[i]]]]=y[i];
for(swap(x,y),i=p=1,x[sa[0]]=0;i<n;i++)
x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
}
for(i=1;i<n;i++) rank[sa[i]]=i;
for(i=k=0;i<n-1;h[rank[i++]]=k)
for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}
int check(int sta)
{
memset(s,0,sizeof(s));
int i,sum=0,l=0;
s[bel[sa[0]]]++,sum+=(s[bel[sa[0]]]==1);
for(i=1;i<n;i++)
{
s[bel[sa[i]]]++,sum+=(s[bel[sa[i]]]==1);
if(h[i]<sta) for(;l<i;l++) s[bel[sa[l]]]--,sum-=(s[bel[sa[l]]]==0);
else if(sum==num) return 1;
}
return 0;
}
int main()
{
scanf("%d",&num);
int i,j,a;
for(i=1;i<=num;i++)
{
scanf("%s",str);
a=strlen(str);
for(j=0;j<a;j++) bel[n]=i,r[n++]=str[j]-'a'+num;
n++;
}
for(i=0;i<n;i++) if(!bel[i]) r[i]=bel[i-1]-1;
m=26+num;
work();
int L=1,R=n/num,mid;
while(L<R)
{
mid=L+R>>1;
if(check(mid)) L=mid+1;
else R=mid;
}
printf("%d\n",L-1);
return 0;
}

【BZOJ2946】[Poi2000]公共串 后缀数组+二分的更多相关文章

  1. [POI2000] 公共串 - 后缀数组,二分

    [POI2000] 公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. Solution 预处理出后缀数组和高度数组,二分答案 \(k\) ,对于每一个连续的 ...

  2. BZOJ2946 [Poi2000]公共串(后缀自动机)

    Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输 ...

  3. 【bzoj2946】[Poi2000]公共串 后缀自动机

    [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1386  Solved: 620[Submit][Status][Discus ...

  4. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

    一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...

  5. [bzoj2946][Poi2000]公共串_后缀数组_二分

    公共串 bzoj-2946 Poi-2000 题目大意:给定$n$个字符串,求他们的最长公共子串. 注释:$1\le n\le 5$,$1\le minlen<maxlen\le 2000$. ...

  6. [BZOJ2946] [Poi2000]公共串解题报告|后缀数组

    给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000     尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...

  7. bzoj3277 串 (后缀数组+二分答案+ST表)

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  8. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  9. [BZOJ3277/BZOJ3473] 串 - 后缀数组,二分,双指针,ST表,均摊分析

    [BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...

随机推荐

  1. DataGridView使用技巧十一:DataGridView用户输入时,单元格输入值的设定

    通过DataGridView.CellParsing事件可以设定用户输入的值.下面的示例:当输入英文文本内容的时候,立即被改变为大写.DataGridView.CellParsing在离开编辑的单元格 ...

  2. mysql编译安装后各种常见错误集锦

    1.ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', sys ...

  3. Jquery同时绑定多个事件

    //JQ 同时绑定多个事件 $("div.div_grren a img").bind({ mouseover:function(){ $(this).attr('src',bor ...

  4. python + opencv: kalman 跟踪

    之前博文中讲解过kalman滤波的原理和应用,这里用一个跟踪鼠标的例程来演示怎么在opencv里用自带的kalman函数进行目标跟踪,文章的内容对做图像跟踪有借鉴意义.文章主要是网络资源进行整理和简单 ...

  5. python 向qq邮箱发邮件

    #coding:utf-8 ''' Created on 2017-1-12 @author: xiaochun ''' import smtplib from email.mime.text imp ...

  6. 用 #include “filename.h” 格式来引用非标准库的头文件

    用 #include “filename.h” 格式来引用非标准库的头文件(编译器将 从用户的工作目录开始搜索) #include <iostream> /* run this progr ...

  7. CommonJS初识

    CommonJS是什么 CommonJS是一个标准库,或者说是一组规范.因为官方并没有给出真正的代码实现,而是给出一些代码组织规范.常用模块的api.包(Package)的命名规范和具体格式. Com ...

  8. thinkphp模板中无法给自定义函数传多个参数

    1.模板的用法 {:function(param1,param2,param3...)} 2.实例 <td>{:getChannelInfo($adminId,$v['sale_id']) ...

  9. PHP实现MySQL数据导出为EXCEL(CSV格式)

    <?php // 输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: application/vnd.ms-excel'); header(' ...

  10. mui自定义事件带参返回mui.back()

    父页面添加自定义监听事件:(e.detail.xxx) window.addEventListener('doit', function(e){ //获取参数值 var imagePath = e.d ...