后缀数组多个字符串问题。

先求出height[]数组,然后二分求最大的长度。

但是条件需要改变。如果出现次数大于一般那就满足。然后就要解决如何判断那一段属于其中一个字符串。

所以先处理出长度。并且不断标记,如果在长度其中,将那个长度标记。那就不会出现自己与自己的相同情况了。

RE了很多次,字符串输入的时候同时存入整数,防止过大可能使字符串出现问题。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include<map>
#define LL long long
using namespace std;
#define maxn 1110000
int max(int x,int y)
{return x>y?x:y;}
int min(int x,int y)
{return x<y?x:y;}
int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
int vex[maxn],size,vis[],pre[maxn],cou;//vex存每一段的长度 size表示个数 pre存满足条件的开始位置 cou存满足的个数
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;
}
int Rank[maxn],height[maxn];
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;
}
int r[maxn],sa[maxn];
int ok(int x,int n,int k)
{
cou=;
int i,j,ret=;
memset(vis,,sizeof(vis));
for(i=;i<=n;i++)
{
if(height[i]>=x)
{
for(j=;j<size;j++)
{
if(sa[i]>vex[j-]&&sa[i]<vex[j])//由于自己添加的并不会相同 所以只要满足在中间位置就可以
{
if(!vis[j])//如果满足就标记掉那个位置
{
vis[j]=;
ret++;
}
}
if(sa[i-]>vex[j-]&&sa[i-]<vex[j])
{
if(!vis[j])
{
vis[j]=;
ret++;
}
}
}
}
else
{
if(ret>k)
{
pre[cou++]=sa[i-]; }
ret=;
memset(vis,,sizeof(vis));
}
}
if(ret>k)
{
pre[cou++]=sa[n];
}
if(cou>)//表面有满足条件的
return ;
return ;
}
char s[maxn],c[maxn];
int main()
{
int i,n,ff=,fl;
while(cin>>n)
{
if(!n)break;
size=;
int len=;
int num=;
for(i=;i<n;i++)
{
scanf("%s",c);
int fl=strlen(c);
for(int p=;p<fl;p++)
{
r[len]=c[p];//修改了此处 过了 之前是先存在s[]中 但是会出现问题 因为100多可能字符有问题
s[len++]=c[p];
}
vex[size++]=len;
r[len]=num;
s[len++]=num++;
}
len--;
int j=len;
r[j]=;
da(r,sa,j+,);
calheight(r,sa,j);
int left,right,mid,ans=-;
left=,right=j,cou=;
while(left<=right)
{
mid=(left+right)/;
if(ok(mid,j,n/))
{
fl=cou;
ans=mid;
left=mid+;
}
else right=mid-;
}
/*for(i=1;i<=j;i++)
printf("%d ",height[i]);
printf("\n");*/
if(ff)
printf("\n");
else ff=;
if(ans<=)
{
printf("?\n");
continue;
}
//printf("%d\n",ans);
for(i=;i<fl;i++)
{
for(j=;j<ans;j++)
{
printf("%c",s[pre[i]+j]);
}
printf("\n");
}
}
}
/*
5
abcdef
bcdea
hzbcde
bcdyz
acxq
*/

最新文章

  1. js词法分析
  2. 从零开始编写自己的C#框架(4)——文档编写说明
  3. 新春测 kinect motor
  4. DDD为何叫好不叫座?兼论DCI与业务分析的方法论
  5. C# 使用xsd文件验证XML 格式是否正确
  6. 信号之sigsetjmp和siglongjmp函数
  7. [转]ASP.NET MVC 入门11、使用AJAX
  8. HDU 2509
  9. 12、SQL Server 行列转换
  10. lseek() 定位一个已经打开的文件
  11. Enterprise Solution 企业管理软件开发框架
  12. nginx反射理传apache配置 - cookie去哪儿了?
  13. ora2pg数据迁移
  14. 软考 程序员 下午考题 c语言 笔记
  15. Linux Ubuntu从零开始部署web环境及项目 -----部署项目 (三)
  16. Spring Cloud Zuul
  17. Log.isLoggable之一正确的使用姿势
  18. Phpstorm数组对齐设置
  19. 报错org.apache.hadoop.mapreduce.lib.input.FileSplit cannot be cast to org.apache.hadoop.mapred.FileSplit
  20. 一款功能强悍的web磁盘管理工具 (A powerful web disk management tools)

热门文章

  1. JSP四大域对象与九大内置对象
  2. HDFS数据读写过程
  3. 数组的方法之(Array.prototype.forEach() 方法)
  4. laravel 下载报错:Unable to guess the mime type as no guessers are available
  5. MySQL错误1055
  6. Apache-Shiro分布式环境配置(与redis集成)(转)
  7. python基础--常用的模块(collections、time、datetime、random、os、sys、json、pickle)
  8. SPSS20.O---软件安装
  9. thinkcmf 导航高亮制作方法(适用于多级导航)(通用)
  10. HDU 1690 最短路