hdu6096 String【AC自动机】
来源:互联网 发布:网上比价软件 编辑:程序博客网 时间:2024/06/03 16:56
题目大意:
给出一些字符串,给出前缀后缀模式询问,问有多少字符串符合该模式
解题思路:
之前一直没头绪,看了看dalao的解法,真是奥妙重重。
对于每个询问,我们将它变成 后缀+分隔符+前缀 的形式,如询问ab cd变为cd{ab。
对于每个原串,我们也变为 原串+分隔符+原串的形式,如abecd变为abecd{abecd。
这时我们若用询问串匹配原串就刚好只能匹配到题目所要求的一段了。
所以处理后直接用询问串建AC自动机即可。
为了避免前后缀重叠的情况,我们记录每个询问串处理后的长度len1和原串处理前的长度len2;
只有len2
最后每个节点记得加上其fail子树中的答案。
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<ctime>#include<queue>#include<vector>#include<set>#include<map>#define ll long longusing namespace std;int getint(){ int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-')c=getchar(),f=-1; for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0'; return i*f;}const int N=100005,M=2000005;struct node{ int son[27],cnt,fail,len;}tr[M];string s[N],t1,t2,t;int T,n,m,tot,ans[M],pos[N];int head,tail,que[M];int Insert(){ int len=t.length(),po=1; for(int i=0;i<len;i++) { if(!tr[po].son[t[i]-'a']) tr[po].son[t[i]-'a']=++tot,tr[tot].len=tr[po].len+1; po=tr[po].son[t[i]-'a']; } tr[po].cnt=1; return po;}void build_fail(){ head=tail=0; que[++tail]=1; while(head<tail) { int u=que[++head]; for(int i=0;i<27;i++) { int v=tr[u].fail,w=tr[u].son[i]; while(!tr[v].son[i])v=tr[v].fail; v=tr[v].son[i]; if(w)tr[w].fail=v,que[++tail]=w; else tr[u].son[i]=v; } }}void ac_auto(int id){ int len=s[id].length(),po=1; for(int i=0;i<len;i++) { po=tr[po].son[s[id][i]-'a']; while(tr[po].len>len/2+1)po=tr[po].fail; ans[po]++; }}void solve(){ for(int i=tail;i;i--) { int u=que[i],v=tr[u].fail; ans[v]+=ans[u]; }}int main(){ //freopen("dictionary.in","r",stdin); //freopen("dictionary.out","w",stdout); T=getint(); while(T--) { memset(tr,0,sizeof(tr)); memset(ans,0,sizeof(ans)); tot=1; for(int i=0;i<27;i++)tr[0].son[i]=1; n=getint(),m=getint(); for(int i=1;i<=n;i++) { cin>>s[i]; s[i]+='{'+s[i]; } for(int i=1;i<=m;i++) { cin>>t1>>t2; t=t2+'{'+t1; pos[i]=Insert(); } build_fail(); for(int i=1;i<=n;i++) ac_auto(i); solve(); for(int i=1;i<=m;i++) cout<<ans[pos[i]]<<'\n'; }}
阅读全文
0 0
- hdu6096 String AC自动机
- hdu6096 String【AC自动机】
- HDU6096 ac自动机+fail树
- HDU 6096 (String) AC自动机
- hdu 6096 String(AC自动机)
- NOIP模拟 string【AC自动机】
- HDU6096 String(Trie树)
- HDU6096 string(字典树)
- [ac自动机]zoj3228 Searching the String
- 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 3228 Searching the String(AC自动机)
- ZOJ 3228 Searching the String AC自动机
- laravel定时任务(使用linux Cron)(转载)
- The origin server did not find a current representation for the target resource or is not willing to
- C++之平衡二叉树的判定(25)---《那些奇怪的算法》
- 排除依赖包,Maven
- java 本地版本切换
- hdu6096 String【AC自动机】
- 数据通信:RIP配置宣告网络号时不带子网掩码?
- java内部类详解
- Linux 中 split 大文件分割和 cat 合并文件
- Linux 常用命令大全
- 阿木实验室 PX4初级视频教程免费版下载地址汇总
- hover给图片加遮罩
- 微服务架构实践心得小结
- 基于LR的新闻多分类(基于spark2.1.0, 附完整代码)