报警了…交了11发WA最后发现第一次因为数组开大RE之后交的代码一直是对的…
100个字符串长度是1000…
我都用的是100…
为什么不RE…QAQ
觉得从RE变成不RE数组就没问题还是too naive
【说好的后缀数组学习笔记呢【下周吧,先跟标准进度
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=205;
const int maxm=101005;
int num[maxm],sa[maxm],Rank[maxm],height[maxm];
int p,wa[maxm],wb[maxm],wv[maxm],cnt[maxm];
int n,m,len[maxn],tot,x,j,l,r,mid,temp,t,ans[maxm];
bool vis[maxn];
char s[maxm];
void DA(int *r,int n,int m)
{
int *x=wa,*y=wb;
for(int i=0;i<m;i++)cnt[i]=0;
for(int i=0;i<n;i++)cnt[x[i]=r[i]]++;
for(int i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;i--)sa[--cnt[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<n;i++)wv[i]=x[y[i]];
for(int i=0;i<m;i++)cnt[i]=0;
for(int i=0;i<n;i++)cnt[wv[i]]++;
for(int i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;i--)sa[--cnt[wv[i]]]=y[i];
swap(x,y);
p=1;x[sa[0]]=0;
for(int i=1;i<n;i++)
x[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+j]==y[sa[i-1]+j]))?p-1:p++;
if(p>=n)break;
m=p;
}
}
void calheight(int *r,int n)
{
n--;
for(int i=1;i<=n;i++)Rank[sa[i]]=i;
int j=0,k=0;
for(int i=0;i<n;height[Rank[i]]=k,i++)
for(k?k--:k=0,j=sa[Rank[i]-1];r[j+k]==r[i+k];k++);
}
bool check(int x)
{
int temp=0;
bool flag=false;
memset(vis,0,sizeof(vis));
for(int i=1;i<tot;i++)
{
if(height[i]>=x)
for(int j=1;j<=n;j++)
{
if(sa[i]>len[j-1] && sa[i]<len[j])temp+=vis[j]?0:1,vis[j]=1;
if(sa[i-1]>len[j-1] && sa[i-1]<len[j])temp+=vis[j]?0:1,vis[j]=1;
}
else
if(temp>n/2)
{
flag=true;
break;
}
else temp=0,memset(vis,0,sizeof(vis));
}
if(temp>n/2)flag=true;
return flag;
}
int main(void)
{
while(scanf("%d",&n) && n)
{
tot=0,temp=30,j=0;
for(int i=1;i<=n;i++)
{
scanf("%s",s+tot);
j=tot;
while(s[tot]!='\0')
{
num[tot]=s[tot]-'a'+1;
tot++;
}
len[i]=tot;
num[tot]=temp++;
tot++;
}
num[tot-1]=0;
num[tot]=temp;
DA(num,tot,temp);
calheight(num,tot);
tot--;
l=0,r=tot;
while(l<r)
{
mid=(l+r)/2;
if(check(mid))l=mid+1;
else r=mid;
}
l--;
if(l)
{
temp=0,t=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<tot;i++)
if(height[i]>=l)
for(int j=1;j<=n;j++)
{
if(sa[i]>len[j-1] && sa[i]<len[j])temp+=vis[j]?0:1,vis[j]=1;
if(sa[i-1]>len[j-1] && sa[i-1]<len[j])temp+=vis[j]?0:1,vis[j]=1;
}
else
{
if(temp>n/2)ans[t++]=sa[i-1];
temp=0;
memset(vis,0,sizeof(vis));
}
if(temp>n/2)ans[t++]=sa[tot-1];
for(int i=0;i<t;i++)
for(int j=0;j<l;j++)
{
printf("%c",s[ans[i]+j]);
if(j==l-1)printf("\n");
}
}
else printf("?\n");
printf("\n");
}
return 0;
}