其他分享
首页 > 其他分享> > P5231 [JSOI2012]玄武密码

P5231 [JSOI2012]玄武密码

作者:互联网

P5231 [JSOI2012]玄武密码

 

 

 

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

const int SZ = 10000005, N = 100005;
int id[1000], len[N], pos[N], ch[SZ][4], fa[SZ], q[SZ], fail[SZ], Index;
bool vis[SZ];
char s[N], t[1000];

void Insert(char *s,int k) {
    int u = 0;
    for (int i = 1; i <= len[k]; ++i) {
        int c = id[(int)s[i]];
        if (!ch[u][c]) ch[u][c] = ++Index, fa[Index] = u;
        u = ch[u][c];
    }
    pos[k] = u;
}
void bfs() {
    int L = 1, R = 0;
    for (int i = 0; i <= 3; ++i) if (ch[0][i]) q[++R] = ch[0][i];
    while (L <= R) {
        int u = q[L ++];
        for (int c = 0; c <= 3; ++c) {
            int v = ch[u][c];
            if (!v) ch[u][c] = ch[fail[u]][c];
            else fail[v] = ch[fail[u]][c], q[++R] = v;
        }
    }
}
int Calc(int x) {
    int ans = len[x];
    for (int i = pos[x]; i; i = fa[i], ans --) 
        if (vis[i]) return ans;
}
int main() {
    int n = read(), m = read();
    id['E'] = 0, id['S'] = 1, id['W'] = 2, id['N'] = 3;
    scanf("%s", s + 1);
    for (int i = 1; i <= m; ++i) {
        scanf("%s", t + 1);
        len[i] = strlen(t + 1);
        Insert(t, i);
    }
    bfs();
    int u = 0, v;
    for (int i = 1; i <= n; ++i) {
        int c = id[(int)s[i]];
        u = ch[u][c];
        v = u;
        while (v && !vis[v]) vis[v] = 1, v = fail[v];
    }
    for (int i = 1; i <= m; ++i) 
        printf("%d\n", Calc(i));
    return 0;
}

 

标签:SZ,JSOI2012,ch,玄武,char,int,P5231,include,getchar
来源: https://www.cnblogs.com/mjtcn/p/10468219.html