【bzoj4327】玄武密码

  • 本文为博主原创,未经许可不得转载

SAM一眼题

出题人丧心病狂卡空间

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
#include<bits/stdc++.h>
#define FILE "read"
#define MAXN (int)1e7+10
using namespace std;
int n,m,cnt(1),now(1),mx[MAXN<<1],par[MAXN<<1],tr[MAXN<<1][4];
char ch[MAXN];
inline int read(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int get(char ch){
if(ch=='S') return 0;
else if(ch=='E') return 1;
else if(ch=='N') return 2;
else return 3;
}
void extend(int x){
int np=++cnt,p=now;
mx[np]=mx[p]+1; now=np;
while(!tr[p][x]&&p) tr[p][x]=np,p=par[p];
if(!p) par[np]=1;
else{
int q=tr[p][x];
if(mx[q]==mx[p]+1) par[np]=q;
else{
int nq=++cnt; mx[nq]=mx[p]+1;
memcpy(tr[nq],tr[q],sizeof(tr[q]));
par[nq]=par[q]; par[q]=par[np]=nq;
while(p&&tr[p][x]==q) tr[p][x]=nq,p=par[p];
}
}
}
int solve(){
scanf("%s",ch+1); int len=strlen(ch+1),now=1;
for(int i=1;i<=len;++i){
int temp=get(ch[i]);
if(tr[now][temp]) now=tr[now][temp];
else return i-1;
}
return len;
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read(); m=read();
scanf("%s",ch+1); int len=strlen(ch+1);
for(int i=1;i<=len;++i) extend(get(ch[i]));
for(int i=1;i<=m;++i) printf("%d\n",solve());
return 0;
}
文章目录
,