vijos-1951 玄武密码
来源:互联网 发布:阿里云创业创新基地 编辑:程序博客网 时间:2024/05/16 01:06
题意:
给出一个匹配串和n个单词;
求每个单词在匹配串中出现的的最大前缀长度;
匹配串长度<=10^7,n<=10^5,单词长度<=100;
题解:
当年啥也不会天真的一发KMP骗掉了50分,然后看题解说是自动机感觉好神啊;
现在回来复习自动机就把这道题切了试试;
基本的建立自动机什么的不说了;
主要就是答案的处理上我是在trie树上记录一个is的数组;
然后每个和匹配串匹配到了的结点全都标记上;
最后和建树时一样扫一遍自动机,每个单词标记的最大前缀长度就是答案;(当然这里要把fail指针的一连串的后缀相同的结点标记)
建树和找答案的复杂度是O(100n),自动机匹配大概是O(10^7)左右咯;
有个小优化,找后缀时发现已经标记的就可以退出了,因为后面一定也被标记完成了;
大概可以省500ms;
还有一点。。。因为匹配串很长字符集很少单词很短;
所以大随机数据可以视为单词全在匹配串中从而可能骗掉4个点233333(orz gaoj,思路太神);
代码:
#include<queue>#include<stdio.h>#include<string.h>#include<algorithm>#define N 100001#define M 10000001using namespace std;queue<int>q;int fail[M], next[M][4], root, tot = 1;char str[M], a[N][101];bool is[M];int f(char a){switch (a){case 'E':return 0;case 'S':return 1;case 'W':return 2;case 'N':return 3;}}void insert(char *s){int p=root,index;while (*s != '\0'){index = f(*s);if (next[p][index] == 0)next[p][index] = ++tot;p=next[p][index];s++;}}void Build(){int p, temp, i;q.push(root);while (!q.empty()){p = q.front(), q.pop();for (i = 0; i < 4; i++){if (next[p][i]){temp = fail[p];while (temp){if (next[temp][i]){fail[next[p][i]] = next[temp][i];break;}temp = fail[temp];}if (!temp)fail[next[p][i]] = root;q.push(next[p][i]);}}}}void query(char *s){int index, p, temp;p = root;while (*s != '\0'){index = f(*s);while (next[p][index] == 0 && p)p = fail[p];p = p ? next[p][index] : root;temp = p;while (temp&&is[temp] == 0){is[temp] = 1;temp = fail[temp];}s++;}}void slove(char *s){int p = root, index, ret = 0;while (*s != '\0'){index = f(*s);if (is[next[p][index]])ret++;elsebreak;p = next[p][index];s++;}printf("%d\n", ret);}int main(){int n, m, i, j, k, len;scanf("%d%d", &len, &n);scanf("%s", str);for (i = root = 1; i <= n; i++){scanf("%s", a[i]);insert(a[i]);}Build();query(str);for (i = 1; i <= n; i++){slove(a[i]);}return 0;}
0 0
- vijos-1951 玄武密码
- 【JSOI2012】【BZOJ4327】玄武密码
- [BZOJ4327] JSOI2012玄武密码
- BZOJ 4327: JSOI2012 玄武密码
- 玄武
- 【bzoj4327】【JSOI2012】【玄武密码】【AC自动机】
- [BZOJ4327][JSOI2012] 玄武密码 后缀自动机
- [BZOJ4327]JSOI2012 玄武密码(AC自动机)
- BZOJ4327 玄武密码 (AC自动机)
- [BZOJ4327]-[JSOI2012]玄武密码-AC自动机
- bzoj 4327: JSOI2012 玄武密码 (AC自动机)
- BZOJ 4327 【JSOI 2012】 玄武密码 AC自动机+dfs
- 魔族密码vijos
- VIJOS P1028 魔族密码
- Vijos P1028魔族密码
- Vijos P1449 字符串还原【密码】
- vijos P1028 魔族密码 DP
- Vijos 1028-魔族密码【暴力】
- [每天读书半小时]6/29 - 30 OpenStack企业云平台架构与实践
- github操作说明
- cygwin :bash: $'…
- 数据库根据实体类自动更新
- NDK C打印log
- vijos-1951 玄武密码
- jni java String 转C char*工具类
- C# Winform 跨线程更新U…
- 用AudioTrack进行音频录制传输
- 标记下,listView与gridView
- jquery的一点点认识
- ECMAScript 6新特性介绍
- C++ strcat
- log4j.properties配置