後綴數組還是不熟
首先總數組的最後一個r[n]必須是0
其次設置的最大值一定要比r中最大值大
再其次 多個字符串拼接時 拼接的字符一定要不相同
最後 題目給的n上限100莫名坑爹
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 4000000+1000;
int t1[maxn],t2[maxn],c[maxn];
int n;
bool cmp(int *r, int a, int b, int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
int len = 0;
void da(int str[], int sa[], int rank[], int height[], int n, int m){
n++;
int i, j, p, *x = t1, *y = t2;
for(int i = 0;i<m;++i)c[i] = 0;
for(int i = 0;i<n;++i)c[x[i]=str[i]]++;
for(int i = 1;i<m;++i)c[i]+=c[i-1];
for(int i =n-1;i>=0;i--)sa[--c[x[i]]] = i;
for(j = 1;j<=n;j<<=1){
p = 0;
for(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<m;++i)c[i] = 0;
for(i = 0;i<n;++i)c[x[y[i]]]++;
for(i = 1;i<m;++i)c[i]+=c[i-1];
for(i = n-1;i>=0;--i)sa[--c[x[y[i]]]] =y[i];
swap(x,y);
p = 1;
x[sa[0]] = 0;
for(i = 1;i<n;++i)
x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
if(p>=n)break;
m = p;
}
int k = 0;
n--;
for(i = 0;i<=n;++i){
rank[sa[i]] = i;
}
for(i = 0;i<n;++i){
if(k)k--;
j = sa[rank[i]-1];
while(str[i+k]==str[j+k]){
k++;
}
height[rank[i]] = k;
}
}
int Rank[maxn],height[maxn];
char str[maxn];
int r[maxn],sa[maxn];
int s[maxn];
int id[maxn];
char ss[2000][2000];
int now_ans[10000];
int ans[10000];
int vis[10000];
int cnt = 0;
int num = 0;
int check(int x,int k){
cnt = 0;
num = 0;
for(int i = 1;i<=300;++i)vis[i] = 0;
// for(int i = 2;i<=n;++i){ n給的100 但是初始化100個肯定錯 不知道原因 這樣寫1000+ms
// if(height[i]<x){
// if(cnt>k){
// ans[num++] = sa[i-1];
// }
// cnt = 0;
// for(int i = 1;i<=300;++i)vis[i] = 0;
// }
// else{
// if(!vis[id[sa[i]]])vis[id[sa[i]]]=1,cnt++;
// if(!vis[id[sa[i-1]]])vis[id[sa[i-1]]]=1,cnt++;
// }
// }
int top = -1;//這樣寫300+ms
int sta[400];
for(int i = 2;i<=n;++i){
if(height[i]<x){
if(cnt>k){
ans[num++] = sa[i-1];
}
cnt = 0;
while(top!=-1){
vis[sta[top--]]= 0;
}
}
else{
if(!vis[id[sa[i]]])vis[id[sa[i]]]=1,cnt++,sta[++top] = id[sa[i]];
if(!vis[id[sa[i-1]]])vis[id[sa[i-1]]]=1,cnt++,sta[++top] = id[sa[i-1]];
}
}
return num;
}
int main(){
int m;
int cas = 0;
while(~scanf("%d",&m)&&m){
n = 0;
int maxs = 130;
int l = 1,right = 0x3f3f3f3f;
for(int i = 1;i<=m;++i){
scanf("%s",ss[i]);
int len = strlen(ss[i]);
right = min(right,len);
for(int j = 0;j<len;++j){
r[++n] = (int)ss[i][j];
id[n] = i;
}
r[++n] = ++maxs;
}
r[n] = 0;
da(r,sa,Rank,height,n,maxs+1);
// for(int i = 1;i<=n;++i){
// cout<<height[i]<<" ";
// }
// cout<<endl;
// for(int i = 1;i<=n;++i){
// cout<<id[i]<<" ";
// }
// cout<<endl;
int now_num = 0;
int length = 0;
// cout<<right<<endl;
while(l<=right){
int mid = (l+right)>>1;
//cout<<mid<<endl;
if(check(mid,m/2)){
now_num = num;
length = mid;
for(int i = 0;i<num;++i){
now_ans[i] = ans[i];
}
l = mid+1;
}
else right = mid - 1;
// cout<<mid<<" "<<num<<endl;
}
// cout<<now_num<<" "<<length<<endl;
if(cas)cout<<endl;
cas++;
if(now_num){
for(int i = 0;i<now_num;++i){
for(int j = now_ans[i];j<now_ans[i]+length;++j){
//cout<<"j"<<j<<endl;
printf("%c",r[j]);
}
printf("\n");
}
}
else{
printf("?\n");
}
}
}