hdu4787 在线ac自动机
来源:互联网 发布:你难忘的事情 知乎 编辑:程序博客网 时间:2024/06/05 01:19
2013 成都赛区 G题
有点难度阿..
题目看错调了两天
通过这题 我了解了何为在线ac自动机
做过的 ac自动机题都是先给好模板串 再给目标串
这样getfail就是遍历一遍节点 就行
于是想到那就每次询问之前都getfail一次吧!
结果TLE..
于是只能看题解..
额..什么叫在线ac自动机?
好吧..在线ac自动机也是每询问一次就getfail一次
那怎么省时间呢?
getfail的时间复杂度就是节点数 那么就减少getfail的节点----开两棵树
一棵小树做缓存buf 每次都对她getfail 大树做堆heap
当小树的size(诶嘿)达到一个数值后就放进 大树就吃了小树(append(), - -)并getfail
询问时同时问大树和小树 求和
#include <stdio.h>#include <string.h>#define ff(i,n) for(int i=0;i<n;i++)const int CH = 2,NODE = 100005;int idx(char x){ return x-'0';}int queue[NODE];struct DFA{ int ch[NODE][CH],f[NODE],val[NODE],last[NODE],sz; void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); } void nn(int u,int c) { memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } void ins(char *s) { int u=0; for(;*s;s++) { int c=idx(*s); if(!ch[u][c]) nn(u,c); u=ch[u][c]; } val[u]=1; } void getfail() { int *rear=queue,*front=queue; ff(c,CH) { int u=ch[0][c]; if(u) f[u]=0,last[u]=0,*rear++=u; } while(rear!=front) { int cur = *front++; ff(c,CH) { int u=ch[cur][c]; int fail=f[cur]; if(u) { while(fail && !ch[fail][c]) fail = f[fail]; f[u]=ch[fail][c]; last[u]=val[f[u]]?f[u]:last[f[u]]; *rear++=u; } } } } int calc(char *s) { int sum=0; int u=0; for(;*s;s++) { int c=idx(*s); while(u&&!ch[u][c]) u=f[u]; u=ch[u][c]; for(int tmp=u;tmp;tmp=last[tmp]) sum+=val[tmp]; } //puts(""); return sum; } int search(char *s) { int u=0; for(; *s; s++) { int c=idx(*s); if(!ch[u][c]) return 0; u=ch[u][c]; } return val[u]; }}heap,buf;void append(int uh,int ub){ heap.val[uh]+=buf.val[ub]; ff(c,CH) { int nh=heap.ch[uh][c]; int nb=buf.ch[ub][c]; if(nb) { if(!nh) { heap.nn(uh,c); nh=heap.ch[uh][c]; } append(nh,nb); } }}void join(){ append(0,0); buf.init(); heap.getfail();}char s[10000005];void move(int n){ //printf("->>%d\n",n); if(!n) return; int len=strlen(s); n%=len; for(int i=0;i<n;i++) s[i+len] = s[i]; s[n+len]=0; strcpy(s,s+n); s[len]=0;}int main(){ int T,cas=1; scanf("%d",&T); while(T--) { printf("Case #%d:\n",cas++); heap.init(); buf.init(); char cmd; int n,flag=0,sft=0;; scanf("%d",&n); while(n--) { getchar(); scanf("%c",&cmd); scanf("%s",s); move(sft); if(cmd=='+') { if(buf.search(s)||heap.search(s)) continue; flag++; buf.ins(s); if(buf.sz>2000) join(),flag=0; } else { if(flag) buf.getfail(); sft=heap.calc(s)+buf.calc(s); printf("%d\n",sft); } } } return 0;}
0 0
- hdu4787 在线ac自动机
- HDU4787--GRE Words Revenge(在线AC自动机)
- [ AC自动机 二进制分组/阈值 ] HDU4787
- 【HDU4787】GRE Words Revenge【AC自动机】【AC自动机合并】
- hdu4787 GRE Words Revenge,AC自动机,平方分割
- [二进制分组+AC自动机] HDU4787 GRE Words Revenge
- [阈值 二进制分组 && AC自动机]HDU4787. GRE Words Revenge
- 【二进制分组+AC自动机】HDU4787[GRE Words Revenge]题解
- hdu 4787 GRE Words Revenge (在线AC自动机)
- HDU 4787 GRE Words Revenge(在线AC自动机)
- HDU 4787 GRE Words Revenge 在线AC自动机
- hdu 4787 GRE Words Revenge(在线AC自动机)
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- 点到线段的最短距离
- 安卓手机WIFI调试COCOS2DX APK
- poj2413 java处理Fibonacci数前500位
- 封装一个类搞定90%安卓客户端与服务器端交互
- php CI框架插入一条或多条sql记录示例
- hdu4787 在线ac自动机
- JDBC高级编程——批处理更新
- redis的pipeline机制解析与注意事项
- HDU 4893 Wow! Such Sequence!
- DSP 资料合集
- 企业网站建设应注重程序美工还是SEO?
- 蛇形矩阵代码篇 一
- NYOJ----333mdd的烦恼
- IOS实用功能之截图(来自相册和拍照)