hdu4787 GRE Words Revenge
来源:互联网 发布:手机密室逃脱推荐 知乎 编辑:程序博客网 时间:2024/05/21 02:51
建立两个AC自动机,每次在小自动机上插入并且暴力重建,当小自动机的点数超过阈值时就把小自动机合并到大自动机上,暴力重建大自动机。注意因为要经常插入重建,需要区分trie树的边和AC自动机上补出来的边。
经过测试,阈值取
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#define LL long longconst int lim=0,maxn=100010,maxl=10000010;int que[maxn];struct acautomaton{ int trie[maxn][2],trans[maxn][2],fail[maxn],tag[maxn],num[maxn],tot; void clear() { for (int i=0;i<=tot;i++) { for (int j=0;j<2;j++) trie[i][j]=trans[i][j]=0; tag[i]=fail[i]=num[i]=0; } tot=0; } int find(char *s,int l) { int p=0; for (int i=0;i<l;i++) if (!trie[p][s[i]-'0']) return 0; else p=trie[p][s[i]-'0']; return tag[p]; } void ins(char *s,int l) { int p=0; for (int i=0;i<l;i++) { if (!trie[p][s[i]-'0']) trie[p][s[i]-'0']=++tot; p=trie[p][s[i]-'0']; } tag[p]=1; } void init() { int hd=1,tl=0,u; for (int i=0;i<2;i++) if (trie[0][i]) { trans[0][i]=trie[0][i]; que[++tl]=trie[0][i]; } while (hd<=tl) { u=que[hd++]; num[u]=tag[u]+num[fail[u]]; for (int i=0;i<2;i++) if (trie[u][i]) { trans[u][i]=trie[u][i]; que[++tl]=trie[u][i]; fail[trie[u][i]]=trans[fail[u]][i]; } else trans[u][i]=trans[fail[u]][i]; } } LL qry(char *s,int l) { int p=0; LL ret=0; for (int i=0;i<l;i++) { p=trans[p][s[i]-'0']; ret+=num[p]; } return ret; }}big,small;void dfs(int &u,int v){ if (!u) u=++big.tot; if (small.tag[v]) big.tag[u]=1; for (int i=0;i<2;i++) if (small.trie[v][i]) dfs(big.trie[u][i],small.trie[v][i]);}void merge(){ for (int i=0;i<2;i++) if (small.trie[0][i]) dfs(big.trie[0][i],small.trie[0][i]);}char s[maxl];void solve(){ LL last=0; int p,q,l; big.clear(); small.clear(); scanf("%d",&q); while (q--) { scanf("%s",s+1); l=strlen(s+1); for (int i=2;i<=l;i++) s[l+i-1]=s[i]; p=last%(l-1)+2; if (s[1]=='+') { if (small.find(s+p,l-1)||big.find(s+p,l-1)) continue; small.ins(s+p,l-1); if (small.tot>lim) { merge(); big.init(); small.clear(); } else small.init(); } else printf("%I64d\n",last=small.qry(s+p,l-1)+big.qry(s+p,l-1)); }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; scanf("%d",&T); for (int K=1;K<=T;K++) { printf("Case #%d:\n",K); solve(); }}
0 0
- hdu4787 GRE Words Revenge
- HDU4787--GRE Words Revenge(在线AC自动机)
- hdu4787 GRE Words Revenge,AC自动机,平方分割
- 【HDU4787】GRE Words Revenge【AC自动机】【AC自动机合并】
- [二进制分组+AC自动机] HDU4787 GRE Words Revenge
- [阈值 二进制分组 && AC自动机]HDU4787. GRE Words Revenge
- 【二进制分组+AC自动机】HDU4787[GRE Words Revenge]题解
- HDU 4787 GRE Words Revenge
- HDU 4787GRE 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自动机)
- HDU 4787 GRE Words Revenge(在线AC自动机)
- HDU 4787 GRE Words Revenge 在线AC自动机
- [二进制分组 AC自动机] HDU 4787 GRE Words Revenge
- hdu 4787 GRE Words Revenge(在线AC自动机)
- HDOJ 题目4787 GRE Words Revenge(在线ac自动机,离线也可做)
- 利用图像处理工具分析MAT中的bitmap
- hdu 2020 绝对值排序
- java乱码问题总结
- cocos creator /1 -hello world
- pyenv进行python版本本地安装
- hdu4787 GRE Words Revenge
- linux下tar.gz zip 解压命令
- sysfs属性旋钮文件实例
- Linux系统非ROOT用户80端口不能启动tomcat问题的变通办法——通过Iptables端口转发
- Java 集合—— LinkedList
- ASP.NET HTML颜色转换成Color值
- 杂乱之android的字体相关类Typeface
- Linux下删除・安装JDK
- swift3.0UIAlertController使用方法