http://poj.org/problem?id=1226

题意:给定n个串。求一个最长的串,使得这个串或者其反串在每个串中都出现过?

思路:先在大串里面加入正反串,然后二分,判定即可。

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
int num[],ws[],wv[],wb[],wa[];
int n,m,rank[],sa[],h[],b[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
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 *sa,int n,int m){
int *y=wb,*x=wa,*t,i,j,p;
for (i=;i<m;i++) ws[i]=;
for (i=;i<n;i++) x[i]=r[i];
for (i=;i<n;i++) ws[x[i]]++;
for (i=;i<m;i++) ws[i]+=ws[i-];
for (i=n-;i>=;i--) sa[--ws[x[i]]]=i;
for (p=,j=;p<n;m=p,j*=){
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<m;i++) ws[i]=;
for (i=;i<n;i++) wv[i]=x[y[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,i=,p=,x[sa[]]=;i<n;i++)
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
void cal(int *r,int n){
int i,j,k=;
for (i=;i<=n;i++) rank[sa[i]]=i;
for (i=;i<n;h[rank[i++]]=k)
for (k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
}
bool check(int x){
int L,R;
int hash[];
for (int i=;i<=n;i++){
L=i;
while (L<=n&&h[L]<x) L++;
if (L>n) break;
R=L;
while (R<=n&&h[R]>=x) R++;
memset(hash,,sizeof hash);
for (int j=L-;j<=R-;j++)
if (b[sa[j]]<=m)
hash[b[sa[j]]]=;
int j=;
for (j=;j<=m;j++)
if (!hash[j]) break;
if (j>m) return ;
i=R;
}
return ;
}
void solve(){
int l=,r=,ans;
while (l<=r){
int mid=(l+r)>>;
if (check(mid)) ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
int main(){
int T=read();
char s[];
while (T--){
m=read();n=;int sx=;
for (int i=;i<=m;i++){
scanf("%s",s);
int len=strlen(s);
for (int j=;j<len;j++)
num[n]=s[j],b[n++]=i;
num[n]=sx++;b[n++]=n+;
for (int j=len-;j>=;j--)
num[n]=s[j],b[n++]=i;
num[n]=sx++;b[n++]=n+;
}
num[n]=;b[n]=n+;
da(num,sa,n+,sx+);
cal(num,n);
solve();
}
}

POJ 1225 Substrings的更多相关文章

  1. OpenJudge/Poj 1226 Substrings

    1.链接地址: http://bailian.openjudge.cn/practice/1226/ http://poj.org/problem?id=1226 2.题目: 总时间限制: 1000m ...

  2. POJ 1226 Substrings(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...

  3. POJ 1226 Substrings

    Substrings Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ID: ...

  4. POJ - 1226 Substrings (后缀数组)

    传送门:POJ - 1226 这个题跟POJ - 3294  和POJ - 3450 都是一样的思路,一种题型. POJ - 3294的题解可以见:https://www.cnblogs.com/li ...

  5. 后缀自动机(SAM)

    *在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符 ...

  6. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  7. kuangbin带你飞 后缀数组 题解

    2份模板 DC3 . 空间复杂度O3N 时间复杂度On #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) #define G(x) ((x) < ...

  8. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  9. 后缀自己主动机(SAM)学习指南

    *在学习后缀自己主动机之前须要熟练掌握WA自己主动机.RE自己主动机与TLE自己主动机* 什么是后缀自己主动机 后缀自己主动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂 ...

随机推荐

  1. 深入 JavaScript(6) - 一静一动

    这里是JavaScript核心的内容了. 挺多的JavaScript测试题也是围绕这个出的. 这里的一静一动指的是: 静, 词法作用域 - Lexical scoping 动, 动态绑定this的值 ...

  2. LINQ TO SQL 常用语法

    LINQ To SQL中IN的用法   IN: C# var result = from s1 in context.Customers where (new string[] { "UK& ...

  3. JDK、JRE和JVM的区别与联系

    首先来说一下JDK JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK). JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime E ...

  4. zookeeper[5] zookeeper集群配置及伪集群配置

    参考:http://zookeeper.apache.org/doc/trunk/zookeeperStarted.html 集群配置: 1.配置文件conf/zoo.cfg,除了单机模式的配置之外, ...

  5. java socket报文通信(一) socket的建立

    TCP是Transfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议.通过TCP协议传输,得到的是一个顺序的无差错的数据流.发送方和接收方的成对的两个socket之间 ...

  6. lesson7:java线程池

    在jdk1.5的版本中,java提供了语言级别的线程池,对于需要使用线程池的业务系统和中间件框架等提供了方便的选择.我认为线程池主要有两个方面的作用:第一就是防止因为外部条件的变化,造成线程数的瞬间飙 ...

  7. for 的多重循环--java

    for的多重循环--java 利用for的多重循环打印出四种不同的三角形的图案. 图案如下: 4种不同三角形图案打印如下------------------******---------------- ...

  8. 为什么要使用Nginx?

    这里做了些基准测试表明nginx打败了其它的轻量级的web服务器和代理服务器,同样也赢了相对不是那么轻量级的产品. 有人说这些基准测试是不准确的,因为在这样那样的环境下,做的比较不一致.我倾向同意基准 ...

  9. 常用渗透性测试工具(Tools for penetration testing)

    常用渗透性测试工具 原文:http://hi.baidu.com/limpid/item/14a2df166adfa8cb38cb3068 对一个应用项目进行渗透性测试一般要经过三个步骤.  第一步, ...

  10. android 判断是否有sim卡及运营商

    判断是否有sim卡的方法:   int absent = TelephonyManager.SIM_STATE_ABSENT; if (1 == absent) { Log.d(TAG,"请 ...