SPOJ220 Relevant Phrases of Annihilation

http://www.spoj.com/problems/PHRASES/

题意:给n个串,求n个串里面都有2个不重叠的最长的字串长度。

思路:二分答案,然后就可以嘿嘿嘿

PS:辣鸡题目毁我青春,一开始二分的时候ans没有赋初值为0,结果没答案的时候就会输出奇怪的数字T_T,其实主要还是怪我不小心。。

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
int len,num[],ws[],wv[],wa[],wb[],h[],sa[],rank[];
int f[][],N,b[];
char s[];
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 *t,*x=wa,*y=wb,i,j,k,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 (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<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=,x[sa[]]=,p=;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 (int i=;i<=n;i++) rank[sa[i]]=i;
for (int i=;i<n;h[rank[i++]]=k){
for (k?k--:,j=sa[rank[i]-];r[j+k]==r[i+k];k++);
}
}
bool check(int mid){
int l,r;
for (int i=;i<=len;i++){
l=i;
while (l<=len&&h[l]<mid) l++;
r=l;
while (r<=len&&h[r]>=mid) r++;
for (int j=;j<=N;j++) f[j][]=0x3f3f3f3f,f[j][]=-0x3f3f3f3f;
for (int j=l-;j<=r-;j++){
int k=b[sa[j]];
if (k==N+) continue;
f[k][]=std::min(f[k][],sa[j]);
f[k][]=std::max(f[k][],sa[j]);
}
int j=;
for (j=;j<=N;j++){
if (f[j][]==0x3f3f3f3f) break;
if (f[j][]-f[j][]<mid) break;
}
if (j>N) 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 ",ans);
}
int main(){
int T=read();
while (T--){
len=;
int n=read();
for (int i=;i<=n;i++){
scanf("%s",s+);
int Len=strlen(s+);
for (int j=;j<=Len;j++)
num[len]=s[j],b[len++]=i;
if (i<n) num[len]=+i,b[len++]=n+;
}
num[len]=;b[len]=n+;
da(num,sa,len+,);
cal(num,len);
N=n;
solve();
}
}
上一篇:Abot爬虫和visjs


下一篇:安装360后,visual studio 经常报各种莫名其妙的错误的解决方案