1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
| #include <bits/stdc++.h>
using namespace std;
const int MAXN = 2100000;
namespace SAM{
int c[MAXN][2],l[MAXN],fa[MAXN],cnt,last,rt;
void init(){rt = last = ++cnt;}
int newnode(int x){l[++cnt] = x;return cnt;}
int ins(int p,int x){
if(c[p][x]){
int q = c[p][x];
if(l[q] == l[p] + 1) last = q;
else{
int nq = newnode(l[p]+1);last = nq;
memcpy(c[nq],c[q],sizeof(c[q]));
fa[nq] = fa[q];fa[q] = nq;
for(;c[p][x] == q;p = fa[p]) c[p][x] = nq;
}
}
else{
int np = newnode(l[p]+1);last = np;
for(;p && (!c[p][x]);p = fa[p]) c[p][x] = np;
if(!p) fa[np] = rt;
else{
int q = c[p][x];
if(l[q] == l[p]+1) fa[np] = q;
else{
int nq = newnode(l[p]+1);
memcpy(c[nq],c[q],sizeof(c[q]));
fa[nq] = fa[q];fa[q] = fa[np] = nq;
for(;c[p][x] == q;p = fa[p]) c[p][x] = nq;
}
}
}
return last;
}
void ins(char *s){
int n = strlen(s),p = rt;
for(int i = 0;i<n;i++) p = ins(p,s[i]-'0');
}
void calmax(int n,char *s,int *res){
int now = rt,cur = 0;
for(int i = 0;i<n;i++){
int x = s[i] - '0';
if(c[now][x]){
cur++,now = c[now][x];
}
else{
while(now && !c[now][x]) now = fa[now];
if(now == 0) now = rt,cur = 0;
else cur = l[now] + 1,now = c[now][x];
}
res[i+1] = cur;
}
}
}
int n,m;
char s[MAXN];
int maxlen[MAXN];
int dp[MAXN];
int q[MAXN],fi,la;
bool check(int n,int L){// 长度为 L 的情况下是否可以实现
fi = 0,la = -1;
for(int i = 0;i < L;i++) dp[i] = 0;
for(int i = L;i <= n;i++){
// printf("%d:%d\n",i,maxlen[i]);
dp[i] = dp[i-1];
while(fi <= la && dp[q[la]] + (i-q[la]) <= dp[i-L] + (i-(i-L))) la--;
q[++la] = i-L;
while(fi <= la && q[fi] < i - maxlen[i]) fi++;
if(fi <= la)
dp[i] = max(dp[i],dp[q[fi]] + (i-q[fi]));
}
// printf("%d\n",dp[n]);
return dp[n] * 10 >= n * 9;
}
int cal(char *s){
int n = strlen(s);
SAM::calmax(n,s,maxlen);
int L = 1,R = 1000000;
while(L != R){
int mid = (L+R+1)/2;
if(!check(n,mid)){
R = mid-1;
}
else{
L = mid;
}
}
return L;
}
void init(){
scanf("%d %d",&n,&m);
SAM::init();
for(int i = 1;i <= m;i++){
scanf("%s",s);
SAM::ins(s);
}
}
void solve(){
for(int i = 1;i<=n;i++){
scanf("%s",s);
printf("%d\n",cal(s));
}
}
int main(){
init();
solve();
return 0;
}
|