ZOJ-3288 AC自动机
来源:互联网 发布:阳泉网络广播电视台 编辑:程序博客网 时间:2024/06/05 18:31
用模式串构造Trie树..用Trie树构造AC自动机...用AC自动机构造Trie图...为了在一个Trie图中能同时处理overlap 和 not overlap的情况..每个节点就要有两个计数器..
overlap的计数器point[h].w[0]很好处理...就是普通的Trie图遍历目标串..到达一个点h..其point[h].w[0]++并且其所有Fail到0的点的w[0]都++...
而对于not overlap的情况..是同样Trie图遍历目标串..但在更新point[h].w[1]时为了避免重叠覆盖...对于每个点h,从根节点到当前点的长度用point[h].length记录..最近一次更新point[h].w[1]时扫到目标串的位置用point[h].last记录...只有当 i-point[h].last>=point[h].length 时才让point[h].w[1]++并且更新point[h].last为i...这样就保证了每次更新point[h].w[1]时不会出现重叠的部分.
Segmentation Fault 了很多次...就是因为节点数开少了...仔细看题才发现题目给的空间是126M...囧..
Program:
#include<iostream>#include<stdio.h>#include<string.h>#include<queue>#define oo 1000000000using namespace std;struct node{ int son[26],fail,w[2],last,length;}point[600005];char s[100005],str[10];int t[100005],a[100005];queue<int> myqueue;int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int T,i,j,n,len,h,num,k; T=0; while (~scanf("%s",s)) { // if (T) printf("\n"); T++; scanf("%d",&n); num=1; memset(point[0].son,0,sizeof(point[0].son)); point[0].last=-oo; point[0].length=0; point[0].w[0]=point[0].w[1]=0; for (j=1;j<=n;j++) { scanf("%d%s",&t[j],&str); len=strlen(str); h=0; for (i=0;i<len;i++) { if (!point[h].son[str[i]-'a']) { point[h].son[str[i]-'a']=++num; memset(point[num].son,0,sizeof(point[num].son)); point[num].last=-oo; point[num].length=point[h].length+1; point[num].w[0]=point[num].w[1]=0; } h=point[h].son[str[i]-'a']; } a[j]=h; } while (!myqueue.empty()) myqueue.pop(); point[0].fail=0; for (i=0;i<26;i++) { point[point[0].son[i]].fail=0; if (point[0].son[i]) myqueue.push(point[0].son[i]); } while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); for (i=0;i<26;i++) { k=point[h].fail; while (k && !point[k].son[i]) k=point[k].fail; point[point[h].son[i]].fail=point[k].son[i]; if (point[h].son[i]) myqueue.push(point[h].son[i]); else point[h].son[i]=point[k].son[i]; } } len=strlen(s); h=0; for (i=0;i<len;i++) { h=point[h].son[s[i]-'a']; k=h; while (k) { point[k].w[0]++; if (i-point[k].last>=point[k].length) { point[k].w[1]++; point[k].last=i; } k=point[k].fail; } } printf("Case %d\n",T); for (i=1;i<=n;i++) printf("%d\n",point[a[i]].w[t[i]]); printf("\n"); } return 0;}
- ZOJ-3288 AC自动机
- zoj 3228 ac自动机
- ZOJ 3430 AC自动机
- zoj 3430(ac自动机)
- zoj 3228(ac自动机)
- ZOJ 3228 AC自动机
- zoj 3430 AC自动机
- ZOJ 3228 AC自动机
- ZOJ-3430 AC自动机+恶心...
- zoj 3545 AC自动机+状态dp
- zoj 3228 Searching the String【ac自动机】
- ZOJ 3430 Detect the Virus AC自动机
- ZOJ 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String(AC自动机)
- 【ZOJ】3430 Detect the Virus AC自动机
- zoj -- 3228 Searching the String(AC自动机)
- Zoj 3430 Detect the Virus (AC自动机)
- ZOJ - 3228 Searching the String (AC自动机)
- Ubuntu 10.10 与 华为 C8650 手机搭建 Android 真机开发调试环境
- sql查询语句——连接查询
- hdu2563
- CListCtrl响应鼠标消息结构转换
- 属于自己的抽屉(初步)
- ZOJ-3288 AC自动机
- 互联网网站架构升级----分布式环境的构建
- 生产和消费
- I Think I Need a Houseboat解题报告
- POJ 3436 最大流
- 中华人民共和国铸币图谱
- AS3 CheckBox ---- 复选框类
- 第八周任务3
- Linux跨平台C++代码解决方案(1)