Description

You are the King of Byteland. Your agents have just intercepted a batch of encrypted enemy messages concerning the date of the planned attack on your island. You immedietaly send for the Bytelandian Cryptographer, but he is currently busy eating popcorn and claims that he may only decrypt the most important part of the text (since the rest would be a waste of his time). You decide to select the fragment of the text which the enemy has strongly emphasised, evidently regarding it as the most important. So, you are looking for a fragment of text which appears in all the messages disjointly at least twice. Since you are not overfond of the cryptographer, try to make this fragment as long as possible.

Input

The first line of input contains a single positive integer t<=10, the number of test cases. t test cases follow. Each test case begins with integer n (n<=10), the number of messages. The next n lines contain the messages, consisting only of between 2 and 10000 characters 'a'-'z', possibly with some additional trailing white space which should be ignored.

Output

For each test case output the length of longest string which appears disjointly at least twice in all of the messages.

Example

Input:
1
4
abbabba
dabddkababa
bacaba
baba Output:
2
/*
SPOJ PHRASES 每个字符串至少出现两次且不重叠的最长子串 因为是求的最长子串,所以考虑二分长度len
然后我们需要对其进行判断,对于每一个连续大于等于len的height[](分组讨论)
记录各个串中的情况,因为要判断不是重叠的,所以对于每个串,我们记录
它满足height>=len的最大最小位置
如果所有串的max-min >= len 则说明存在长度为len的子串在
每个串都有出现两次且不重叠 感觉思路没什么问题,主要是最开始代码写得不够简洁,而且WR hhh-2016-03-21 23:01:01
*/
#include <algorithm>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <map>
#include <cstdio>
#include <vector>
#include <functional>
#define lson (i<<1)
#define rson ((i<<1)|1)
using namespace std;
typedef long long ll;
const int maxn = 101000; int t1[maxn],t2[maxn],c[maxn];
bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b] &&r[l+a] == r[l+b];
} void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)
{
n++;
int p,*x=t1,*y=t2;
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[i] = str[i]]++;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i>=0; i--) sa[--c[x[i]]] = i;
for(int j = 1; j <= n; j <<= 1)
{
p = 0;
for(int i = n-j; i < n; i++) y[p++] = i;
for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[y[i]]]++ ;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y);
p = 1;
x[sa[0]] = 0;
for(int i = 1; i < n; i++)
x[sa[i]] = cmp(y,sa[i-1],sa[i],j)? p-1:p++;
if(p >= n) break;
m = p;
}
int k = 0;
n--;
for(int i = 0; i <= n; i++)
Rank[sa[i]] = i;
for(int i = 0; i < n; i++)
{
if(k) k--;
int j = sa[Rank[i]-1];
while(str[i+k] == str[j+k]) k++;
height[Rank[i]] = k;
}
} int Rank[maxn];
int sa[maxn];
int str[maxn],height[maxn];
char s[maxn];
int id[maxn];
struct node
{
int Min;
int Max;
int flag;
} anspos[15]; void ini()
{
for(int i = 0; i <= 12; i++)
anspos[i].Min = 0x3f3f3f3f,anspos[i].Max = -1;
} bool can(int len,int n,int num)
{
int l = 2,r = 2;
ini();
for(int i = 2; i <= n; i++)
{
if(height[i] >= len)
{
int id1=id[sa[i-1]];
int id2=id[sa[i]]; anspos[id1].Max=max(anspos[id1].Max,sa[i-1]);
anspos[id1].Min=min(anspos[id1].Min,sa[i-1]); anspos[id2].Max=max(anspos[id2].Max,sa[i]);
anspos[id2].Min=min(anspos[id2].Min,sa[i]);
int t;
for(t = 0; t < num; t++)
if(anspos[t].Max - anspos[t].Min < len)
break;
if(t == num)
return 1;
}
else
{
for(int j = 0; j <= 10; j++)
anspos[j].Min = 0x3f3f3f3f,anspos[j].Max = -1;
}
}
for(int i = 0; i < num; i++)
if(!anspos[i].flag)
return 0;
return 1;
} int main()
{
int k,n,t;
scanf("%d",&t);
while(t--)
{
ini();
int tot = 0,len = 0x3f3f3f3f;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%s",s);
for(int j = 0; s[j]!='\0'; j++)
{
id[tot] = i;
str[tot++] = s[j]-'a'+10;
}
id[tot] = i;
str[tot++] = i;
len = min(len,(int)strlen(s));
}
str[tot] = 0;
get_sa(str,sa,Rank,height,tot,100);
int l = 0,r = len;
int ans = 0;
while(l <= r)
{
int mid = (l+r)>>1;
if(can(mid,tot,n))
{
ans = mid;
l = mid+1;
}
else
r = mid-1;
}
printf("%d\n",ans);
}
return 0;
}

  

SPOJ PHRASES 每个字符串至少出现两次且不重叠的最长子串的更多相关文章

  1. SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串

    题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags  You ...

  2. hdoj 3746 Cyclic Nacklace【KMP求在结尾加上多少个字符可以使字符串至少有两次循环】

    Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  3. SPOJ - PHRASES Relevant Phrases of Annihilation (后缀数组)

    You are the King of Byteland. Your agents have just intercepted a batch of encrypted enemy messages ...

  4. POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)

    多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...

  5. SPOJ - PHRASES K - Relevant Phrases of Annihilation

    K - Relevant Phrases of Annihilation 题目大意:给你 n 个串,问你最长的在每个字符串中出现两次且不重叠的子串的长度. 思路:二分长度,然后将height分块,看是 ...

  6. SPOJ PHRASES 后缀数组

    题目链接:http://www.spoj.com/problems/PHRASES/en/ 题意:给定n个字符串,求一个最长的子串至少在每个串中的不重叠出现次数都不小于2.输出满足条件的最长子串长度 ...

  7. SPOJ - PHRASES Relevant Phrases of Annihilation

    传送门:SPOJ - PHRASES(后缀数组+二分) 题意:给你n个字符串,找出一个最长的子串,他必须在每次字符串中都出现至少两次. 题解:被自己蠢哭...记录一下自己憨憨的操作,还一度质疑评测鸡( ...

  8. 华为 1.static有什么用途?(请至少说明两种)

    1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问 ...

  9. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

随机推荐

  1. Linux学习--线程控制

    关于线程控制,主要就是几个模块,我们一个一个消灭.消化: 一.线程创建: 1.先来看看在Linux环境下的线程创建函数: 分析:意思很明显: 1.函数名是 pthread_create  : 2.功能 ...

  2. 十款不容错过的Swift iOS开源项目及介绍

    1.十款不容错过的Swift iOS开源项目. http://www.csdn.net/article/2014-10-16/2822083-swift-ios-open-source-project ...

  3. 关于第一次使用vue-cli

    前段时间终于终于可以用vue-cli,webpack做个企业站,记一下过程... 首先node.js,按照vue官网的步骤命令提示符走一波,网速原因,所以用的是淘宝镜像 cnpm # 全局安装 vue ...

  4. Flask Session 详解

    会话session ,允许你在不同请求 之间储存信息.这个对象相当于用密钥签名加密的 cookie ,即用户可以查看你的 cookie ,但是如果没有密钥就无法修改它. from flask impo ...

  5. Apache的配置httpd.conf文件配置

    (1) 基本配置: ServerRoot "/mnt/software/apache2" #你的apache软件安装的位置.其它指定的目录如果没有指定绝对路径,则目录是相对于该目录 ...

  6. Java代码风格和在idea中的一些设置

    源文件基本设置 1. 文件名 驼峰标识,.java结尾 2. 编码 统一为UTF-8 Transport...可以解决property文件不能正常显示为中文的问题 3. 特殊字符 尽量使用转义字符(\ ...

  7. SourceTree 实现 git flow 流程

    为什么使用 git 和 git flow,这篇文章 深入理解学习Git工作流 的内容相信能够给你一个完整的答案. 我们以使用SVN的工作流来使用git有什么不妥? git 方便的branch在哪里,团 ...

  8. 使用JDBC中的出现的乱码和查询无结果问题

    使用JDBC中的问题 连接的后出现查询结果是乱码. 1.可能是代码的编码与数据库的编码不同 ​ 有可以将二者都设置为UTF-8 2.如果比较懒得话可以只设代码为UTF-8 mysql 连接url中us ...

  9. 进军ABP第一天:ABP理论知识

    1.2.3 领域层领域层就是业务层,是一个项目的核心,所有业务规则都应该在领域层实现. ( 实体(Entity ) 实体代表业务领域的数据和操作,在实践中,通过用来映射成数据库表. ( 仓储(Repo ...

  10. 【问题解决】jhipster-registry-master空白页

    问题概述: 刚从github拉下来的jhipster-registry-master直接运行,访问http://localhost:8761会发现会空白页,但是网页的title显示正常,本文目的是解决 ...