分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

BZOJ【bzoj1030】[JSOI2007]文本生成器(AC自动机)

发布时间:2023-09-06 01:37责任编辑:赖小花关键词:暂无标签

做到了AC自动机的题目,复习了一下AC自动机,学习了黄学长代码,这个题呢,我们可以模拟在AC自动机上的操作,dp数组f[i][j]表示前i个字符,我们在AC自动机上处在j号节点的方案数。

我们可以计算不符合条件的方案数,转移的时候不在有标记的节点转移就行了。—— by VANE

#include<bits/stdc++.h>using namespace std;const int N=6005;struct node{ ???int son[26],danger,fail;}ch[N];int n,m,f[105][6005],tot=1;const int mod=10007;char t[105];void insert(char s[]){ ???int now=1,len=strlen(s); ???for(int i=0;i<len;++i) ???{ ???????int w=s[i]-‘A‘; ???????if(ch[now].son[w]) now=ch[now].son[w]; ???????else now=ch[now].son[w]=++tot; ???} ???ch[now].danger=1;}void acmach(){ ???queue<int> q; ???q.push(1);ch[1].fail=0; ???while(!q.empty()) ???{ ???????int u=q.front();q.pop(); ???????for(int i=0;i<26;++i) ???????{ ???????????if(!ch[u].son[i]) continue; ???????????int v=ch[u].fail; ???????????while(!ch[v].son[i]) v=ch[v].fail; ???????????ch[ch[u].son[i]].fail=ch[v].son[i]; ???????????if(ch[ch[v].son[i]].danger) ch[ch[u].son[i]].danger=1; ???????????q.push(ch[u].son[i]); ???????} ???}}void dp(int x){ ???for(int i=1;i<=tot;++i) ???{ ???????if(ch[i].danger||!f[x-1][i]) continue; ???????for(int j=0;j<26;++j) ???????{ ???????????int k=i; ???????????while(!ch[k].son[j]) k=ch[k].fail; ???????????????????????f[x][ch[k].son[j]]=(f[x][ch[k].son[j]]+f[x-1][i])%mod; ???????} ???}}int main(){ ???scanf("%d%d",&n,&m); ???for(int i=0;i<26;++i) ch[0].son[i]=1; ???for(int i=1;i<=n;++i) ???{ ???????scanf("%s",t); ???????insert(t); ???} ???acmach(); ???f[0][1]=1; ???for(int i=1;i<=m;++i) dp(i); ???int sum=1; ???for(int i=1;i<=m;++i) sum=sum*26%mod; ???for(int i=1;i<=tot;++i) ???if(!ch[i].danger) sum=(sum-f[m][i]+mod)%mod; ???cout<<sum;}

BZOJ【bzoj1030】[JSOI2007]文本生成器(AC自动机)

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8318912.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved