博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HihoCoder 1877 - Approximate Matching
阅读量:5025 次
发布时间:2019-06-12

本文共 2698 字,大约阅读时间需要 8 分钟。

题目链接:

 

题意:

  给定一个字符串,问有多少长度为 m 的字符串弱包含这个字符串。弱包含被定义为包含这个字符串或者包含这个字符串任意更改一位之后的字符串。

 

题解:

  基本的 AC 自动机上 dp,先将所有可能匹配的串放到一个自动机里,每个节点的 dp[i] 表示匹配到当前节点的长度为 i 的字符串个数。先构建 fail 指针代表失配的走向,再构建 next 指针代表每一个节点,确定下一位的值后最终匹配到的节点。此时,只要在自动机上根据 next 指针 dp 就可以了。

 

#include
#include
#include
#include
using namespace std;typedef long long ll;const int maxn=1e5+5,maxm=3e6+5,cut=300;struct node{ node *fa,*ch[26],*fail; int end,cnt; node(){ fa=fail=NULL; end=cnt=0; fill(ch,ch+26,fa); } inline void set_fail(node *u){ fail=u; cnt=end+(u->cnt); }};node *merge_node(node *a,node *b){ if (!a) return b; if (!b) return a; int i; node *v; for (i=0;i<26;i++){ v=a->ch[i]=merge_node(a->ch[i],b->ch[i]); if (v) v->fa=a; } a->end+=b->end; delete b; return a;}node *que[maxm];struct ac_auto{ node *root; int size; ac_auto(){ root=new node; size=0; } void clear(){ int i,l,r; node *u,*v; l=r=0; que[r++]=root; while (l
ch[i]) que[r++]=v; delete u; } root=new node; size=0; } void add_str(char s[]){ node *u,*v; int i,id; u=root; for (i=0;s[i]!='\0';i++){ id=s[i]-'a'; v=u->ch[id]; if (!v){ v=new node; u->ch[id]=v; v->fa=u; } u=v; } v->end++; size+=i; } void merge_ac(ac_auto &b){ size+=b.size; root=merge_node(root,b.root); b.root=new node; b.size=0; } void build_fail(){ int i,l,r; node *u,*v,*w; l=0; r=0; for (i=0;i<26;i++) if (v=root->ch[i]){ v->set_fail(root); que[r++]=v; } while (l
ch[i]){ que[r++]=v; w=u->fail; while (w!=root){ if (w->ch[i]){ v->set_fail(w->ch[i]); break; } w=w->fail; } if (w==root){ if (w->ch[i]) v->set_fail(w->ch[i]); else v->set_fail(root); } } } } ll query(char s[]){ node *u; int i,id; ll ans; u=root; ans=0; for (i=0;s[i]!='\0';i++){ id=s[i]-'a'; while (u!=root){ if (u->ch[id]){ u=u->ch[id]; break; } u=u->fail; } if (u==root){ if (u->ch[id]) u=u->ch[id]; else u=root; } ans+=u->cnt; } return ans; }};ac_auto ac[maxn];char s[maxn];int main(){ int tt; int i,j,n,m,op; int siz; ll ans; scanf("%d",&tt); siz=0; while (tt--){ scanf("%d%d",&n,&m); for (i=0;i
1&&ac[siz-1].size*2>ac[siz-2].size){ ac[siz-2].merge_ac(ac[siz-1]); siz--; } ac[siz-1].build_fail(); } else{ ans=0; for (j=0;j

 

转载于:https://www.cnblogs.com/Kilo-5723/p/10669041.html

你可能感兴趣的文章
tail -f 和 -F 的用法
查看>>
网络协议研究(四)FTP
查看>>
全文检索-Elasticsearch (四) elasticsearch.net 客户端
查看>>
Oracle DBMS_SESSION
查看>>
sublime复制当前行到下一行
查看>>
WPF 3D变换应用
查看>>
luogu4012 深海机器人问题 网络流
查看>>
android 拍照上传照片
查看>>
SELECT INTO 和 INSERT INTO SELECT 两种表复制语句(转载)
查看>>
数据结构上机任务
查看>>
centos7上安装mysql
查看>>
浮动的label
查看>>
Python --文件的读写
查看>>
乱码问题
查看>>
hdu1671Phone List(字典树)
查看>>
访客至上的Web、移动可用性设计--指导原则
查看>>
常用模块一
查看>>
类和对象
查看>>
追剧《大秦帝国》之感
查看>>
[转] Python Traceback详解
查看>>