Description

You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.

Input

The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed
by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.

Output

There should be one line per test case containing the length of the largest string found.

Sample Input

2
3
ABCD
BCDFF
BRCD
2
rose
orchid

Sample Output

2
2

Source


题意:给定n个字符串,求出现或反转后出如今每一个字符串中的最长子串。 
思路:先将每一个字符串都反过来写一遍。中间用一个互不同样的 





且没有出如今字符串中的字符隔开,再将n个字符串所有连起来,中间也是用一 





个互不同样的且没有出如今字符串中的字符隔开,求后缀数组。然后二分答案。 





再将后缀分组。推断的时候,要看是否有一组后缀在每一个原来的字符串或反转后 





的字符串中出现。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std; #define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 1000005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
int wa[N],wb[N],wsf[N],wv[N],sa[N];
int rank[N],height[N],s[N],a[N];
//sa:字典序中排第i位的起始位置在str中第sa[i]
//rank:就是str第i个位置的后缀是在字典序排第几
//height:字典序排i和i-1的后缀的最长公共前缀
int cmp(int *r,int a,int b,int k)
{
return r[a]==r[b]&&r[a+k]==r[b+k];
}
void getsa(int *r,int *sa,int n,int m)//n要包括末尾加入的0
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=0; i<m; i++) wsf[i]=0;
for(i=0; i<n; i++) wsf[x[i]=r[i]]++;
for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i;
p=1;
j=1;
for(; 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++) wv[i]=x[y[i]];
for(i=0; i<m; i++) wsf[i]=0;
for(i=0; i<n; i++) wsf[wv[i]]++;
for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
t=x;
x=y;
y=t;
x[sa[0]]=0;
for(p=1,i=1; i<n; i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
}
}
void getheight(int *r,int n)//n不保存最后的0
{
int i,j,k=0;
for(i=1; i<=n; i++) rank[sa[i]]=i;
for(i=0; i<n; i++)
{
if(k)
k--;
else
k=0;
j=sa[rank[i]-1];
while(r[i+k]==r[j+k])
k++;
height[rank[i]]=k;
}
} char str[N];
int len[105],size,ans[N],id[N];
bool vis[105]; bool check(int mid,int n,int k)
{
int i,j;
int size = 0,cnt = 0;
MEM(vis,false);
for(i = 1; i<=n; i++)
{
if(height[i]>=mid)
{
for(j = 0; j<k; j++)
{
if(id[sa[i]]==j) cnt+=(vis[j]?0:1),vis[j]=true;
if(id[sa[i-1]]==j) cnt+=(vis[j]? 0:1),vis[j]=true;
}
}
else
{
if(cnt>=k) return true;
cnt = 0;
MEM(vis,false);
}
}
if(cnt>=k) return true;
return false;
} int main()
{
int n,k,i,j,flag = 0,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&k);
n = 0;
size = 0;
int p = 1;
for(i = 0; i<k; i++)
{
scanf("%s",str);
int ll = strlen(str);
for(j = 0; j<ll; j++)
{
id[n] = i;
s[n++] = str[j];
}
s[n++] = '#'+(p++);
for(j = ll-1; j>=0; j--)
{
id[n] = i;
s[n++] = str[j];
}
s[n++] = '#'+(p++);
}
s[n-1] = 0;
getsa(s,sa,n,255);
getheight(s,n-1);
int l=1,r=n,mid,ans = 0;
while(l<=r)
{
mid = (l+r)/2;
if(check(mid,n,k))
{
ans = mid;
l = mid+1;
}
else r = mid-1;
}
printf("%d\n",ans);
} return 0;
}

POJ1226:Substrings(后缀数组)的更多相关文章

  1. POJ1226 Substrings ——后缀数组 or 暴力+strstr()函数 最长公共子串

    题目链接:https://vjudge.net/problem/POJ-1226 Substrings Time Limit: 1000MS   Memory Limit: 10000K Total ...

  2. UVALive - 6869 Repeated Substrings 后缀数组

    题目链接: http://acm.hust.edu.cn/vjudge/problem/113725 Repeated Substrings Time Limit: 3000MS 样例 sample ...

  3. POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数

    题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K ...

  4. SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数

    题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...

  5. SPOJ- Distinct Substrings(后缀数组&后缀自动机)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  6. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  7. POJ 3415 Common Substrings 后缀数组+并查集

    后缀数组,看到网上很多题解都是单调栈,这里提供一个不是单调栈的做法, 首先将两个串 连接起来求height   求完之后按height值从大往小合并.  height值代表的是  sa[i]和sa[i ...

  8. SPOJ DISUBSTR Distinct Substrings 后缀数组

    题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...

  9. ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...

随机推荐

  1. Google Chrome: Make the Bookmarks Bar Display as Icons Only

    By reducing your bookmarks to show only the icons, you can access more of them from the Bookmarks ba ...

  2. HTTP协议状态码详解(HTTP Status Code)

    转自:http://www.cnblogs.com/shanyou/archive/2012/05/06/2486134.html 使用ASP.NET/PHP/JSP 或者javascript都会用到 ...

  3. 借助阿里AntUI元素实现两个Web页面之间的过渡——“Loading…”

    今天遇到了这么个问题,如下: 功能需求:有两个页面A和B,点击A中的"确定"按钮,超链接到页面B,在跳转到B页面时出现“Loading”的样式. 需求分析:作为一个后端程序员,一开 ...

  4. EL表达式的操作符

    表9.1 EL表达式的操作符 操作符 功能和作用 . 访问一个bean属性或者Map entry [] 访问一个数组或者链表元素 () 对子表达式分组,用来改变赋值顺序 ? : 条件语句,比如:条件? ...

  5. UnicodeDecodeError while using json.dumps()

    UnicodeDecodeError 系统.文件.vim全部设置为utf-8 export LANG=zh_CN.UTF8 # coding:utf-8 json.dumps(content, ens ...

  6. centos基本操作

    yum install nodejs npm install -g shadowsocks nohup ssserver & 后台运行 vi /usr/lib/node_modules/sha ...

  7. js如何实现继承

    js继承有5种实现方式:1.继承第一种方式:对象冒充  function Parent(username){    this.username = username;    this.hello = ...

  8. paip.提升效率---提升绑定层次--form绑定取代field绑定

    paip.提升效率---提升绑定层次--form绑定取代field绑定 =================== 编辑form中,常常需要,绑定一个对象到个form..   传统上要绑定field开始. ...

  9. 从MySQL 5.5到5.7看复制的演进

    概要:MySQL 5.5 支持单线程模式复制,MySQL 5.6 支持库级别的并行复制,MySQL 5.7 支持事务级别并行复制.结合这个主线我们可以来分析一下MySQL以及社区发展的一个前因后果. ...

  10. wicket基础应用(1)--使用wicket对表单中的数据进行验证

    作者:lhx1026 出处:http://lhx1026.iteye.com/ wicket基础应用(1)--使用wicket对表单中的数据进行验证 举个例子: 1.有一个Java文件SysCharg ...