zoj -- 3228 Searching the String(AC自动机)
来源:互联网 发布:二桃杀三士 知乎 编辑:程序博客网 时间:2024/05/03 11:16
给出一个字符串。有n个询问,0 string表示string在字符串中出现多少次,可以重叠。1 string表示string在字符串中出现多少次,string不能重叠。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3228
维护一个last数组,记录该字符串上次出现的位置,根据这个来判断有没有重叠。
//#pragma comment(linker,"/STACK:1024000000,1024000000")#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <cstdio>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef double DB;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pb push_back#define MP make_pair#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 100000;const int maxn = 600000 + 10;char str[100010], ss[100];int n, op[100010], pos[100010], cas = 0;int tot[maxn][2], last[maxn];int d[maxn];const int max_chd = 26;///字母表大小struct AC_automata{ int chd[maxn][max_chd], fail[maxn], cnt[maxn];///trie中的chd数组,fail指针,节点标记(是多少个串的结尾) int root, sz;///根节点,trie树大小 int newnode(){///建立新的节点,返回节点编号 for(int i=0; i<max_chd; i++) chd[sz][i] = -1; d[sz] = 0; cnt[sz++] = 0; return sz - 1; } void init(){ sz = 0; root = newnode(); } int ID(char ch){ return ch - 'a'; } int Insert(char * str){///建trie树 int cur = root; int len = strlen(str); for(int i=0; i<len; i++){ if(chd[cur][ID(str[i])] == -1) chd[cur][ID(str[i])] = newnode(), d[chd[cur][ID(str[i])]] = i + 1; cur = chd[cur][ID(str[i])]; } cnt[cur]++; return cur; } void build(){///构建fail指针 queue<int> Q; while(!Q.empty()) Q.pop(); fail[root] = root; for(int i=0; i<max_chd; i++){ if(chd[root][i] == -1) chd[root][i] = root; else{ fail[chd[root][i]] = root; Q.push(chd[root][i]); } } while(!Q.empty()){ int now = Q.front(); Q.pop(); for(int i=0; i<max_chd; i++){ if(chd[now][i] == -1) chd[now][i] = chd[fail[now]][i]; else { fail[chd[now][i]] = chd[fail[now]][i]; Q.push(chd[now][i]); } } } } void Query(char * str){ memset(tot, 0, sizeof(tot)); memset(last, -1, sizeof(last)); int now = root; int len = strlen(str); for(int i=0; i<len; i++){ now = chd[now][ID(str[i])]; int tmp = now; while(tmp != root){ if(cnt[tmp]){ tot[tmp][0]++; if(i - last[tmp] >= d[tmp]) tot[tmp][1]++, last[tmp] = i; } tmp = fail[tmp]; } } for(int i=0; i<n; i++){ printf("%d\n", tot[pos[i]][op[i]]); } }}AC;int main(){ while(scanf("%s", str) == 1){ scanf("%d", &n); AC.init(); for(int i=0; i<n; i++){ scanf("%d%s", &op[i], ss); pos[i] = AC.Insert(ss); } AC.build(); printf("Case %d\n", ++cas); AC.Query(str); puts(""); } return 0;}
0 0
- zoj 3228 Searching the String【ac自动机】
- ZOJ 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String(AC自动机)
- zoj -- 3228 Searching the String(AC自动机)
- ZOJ - 3228 Searching the String (AC自动机)
- zoj 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String AC自动机
- zoj 3228 Searching the String (ac自动机)
- zoj 3228 Searching the String 【AC自动机】
- ZOJ 3228 Searching the String(AC自动机)
- [AC自动机] zoj Searching the String
- ZOJ Problem Set - 3228 Searching the String AC自动机
- ZOJ 3228 Searching the String (AC自动机)
- ZOJ 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String (AC自动机)
- zoj 3228 Searching the String(AC自动机基本应用)
- ZOJ 3328 Searching the String (AC自动机)
- ZOJ 3228Searching the String AC自动机的不重复匹配
- 新顶级域名+2G建站空间免费送企业商城、手机站、微站,仅需756元!
- java写的一个递归程序
- Android 实时动态刷新更改菜单
- js 获取当前国家 省份 城市等信息
- 神奇的运行
- zoj -- 3228 Searching the String(AC自动机)
- 数据库的一些基本概念(二)
- 对quagga(zebra)的cmd声明宏的学习
- 个人奋斗和工人房地摊货女人分
- 动态维护中位数
- OAF 当前时间格式化
- uva_ 575-Skew Binary
- 验证Email
- poj 1915&&poj 2243 Knight Moves (bfs搜索)