[jzoj3472]【NOIP2013模拟联考8】匹配(match)
来源:互联网 发布:瓷砖的重量怎么算法 编辑:程序博客网 时间:2024/06/08 14:18
Description
给定k个字符串以及长度为n的母串可选字母的集合,问母串要完整出现给定的k个字符串的方案数,答案模1000000007,字符仅包含小写字母。
Solution
注意到 k 很小 可以状压
很容易想到利用 AC 自动机 来记录当前匹配到各个字符串的位置
枚举下一个出现的字符即可
注意 在更新时,指针走到了一个节点j,不能只加上这一个节点的贡献,而要把其对应的fail都给更新到
或者 你可以提前把这些点一并考虑
Code
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define fo(i,x,y) for (int i=(x);i<=(y);++i)#define fd(i,x,y) for (int i=(x);i>=(y);--i)#define oo 2139062143using namespace std;typedef long long ll;typedef double db;const int N=110,M=11,K=9,Mo=1e9+7,LEN=33;const int P=K*LEN;int n,k;char st[K][LEN];int d[P];int all;int f[N][P][256+100];bool bcz[26];int chos[26];struct ACAutoMachine{ int chd[P][26]; int fail[P]; int sz,pt,bz[P]; void insert(char *c,int w) { int len=strlen(c),tmp=0; fo(i,0,len-1) { int now=c[i]-'a'; if(!chd[tmp][now]) { chd[tmp][now]=++sz; memset(chd[sz],0,sizeof chd[sz]); } tmp=chd[tmp][now]; } bz[tmp]|=(1<<(w-1)); } bool pd[P]; void Getfail() { memset(pd,0,sizeof pd); int hd=0,tl=0; pd[0]=1; fo(i,0,25) if(chd[0][i]) d[++tl]=chd[0][i],pd[d[tl]]=1; while(hd++<tl) { int now=d[hd]; fo(i,0,25) if(chd[now][i]) { int v=chd[now][i]; if(pd[v]) continue; pd[v]=1; d[++tl]=v; int rt=fail[now]; while(!chd[rt][i]&&rt) rt=fail[rt]; fail[v]=chd[rt][i]; } } fo(i,0,sz) { bz[i]|=bz[fail[i]]; fo(j,0,25) { int p=i; while(p&&!chd[p][j]) p=fail[p]; if(chd[p][j]) next[i][j]=chd[p][j]; else next[i][j]=0; } } } int dt[2][P][2]; int tot[2]; int next[P][25]; void solve() { memset(f,0,sizeof f); f[0][0][0]=1; fo(i,0,n-1) { fo(j,0,sz) { fo(s,0,all) if(f[i][j][s]) { fo(cc,1,chos[0]) { int c=chos[cc]; int jj=next[j][c],ss=s|bz[jj]; f[i+1][jj][ss]=(f[i+1][jj][ss]+f[i][j][s])%Mo; } } } } int ans=0; fo(i,0,sz) { ans=(ans+f[n][i][all])%Mo; } printf("%d\n",ans); } void clear() { memset(bz,0,sizeof bz); memset(next,0,sizeof next); memset(fail,0,sizeof fail); memset(chd[0],0,sizeof chd[0]); pt=sz=0; } }ac;int m;int main(){ scanf("%d%d\n",&n,&k); fo(i,1,k) { scanf("%s\n",st[i]); ac.insert(st[i],i); } ac.Getfail(); scanf("%d\n",&m); fo(i,1,m) { char tp=getchar(); while(!(tp<='z'&&tp>='a')) tp=getchar(); bcz[tp-'a']=1; } fo(i,0,25) if(bcz[i])chos[++chos[0]]=i; all=(1<<k)-1; ac.solve(); return 0;}
阅读全文
0 0
- [jzoj3472]【NOIP2013模拟联考8】匹配(match)
- 3472. 【NOIP2013模拟联考8】匹配(match)
- [jzoj]3472. 【NOIP2013模拟联考8】匹配(match)(AC自动机+DP)
- 【NOIP2013模拟联考13】线段
- 【NOIP2013模拟联考7】数列
- 【NOIP2013模拟联考5】军训
- 【NOIP2013模拟联考6】选课
- 【NOIP2013模拟联考7】OSU
- JZOJsenior3470.【NOIP2013模拟联考8】最短路(path)
- 【NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考6】选课(select)
- 【NOIP2013模拟联考5】军训(training) 题解
- NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考2】摘取作物(pick)
- 【NOIP2013模拟联考3】山峰(summits)
- 【NOIP2013模拟联考15】人类基因组(genes)
- 【NOIP2013模拟联考10】独立集(bubble)
- JZOJsenior3484.【NOIP2013模拟联考10】密码(substring)
- 枚举类型中的values()方法初探
- A11_C#封装的委托
- 参数优化,iostat详解
- Leetcode 82. Remove Duplicates from Sorted List II
- 51nod1273 旅行计划 贪心
- [jzoj3472]【NOIP2013模拟联考8】匹配(match)
- MSCVP140d.dll 缺失找不到的一种情况
- High Performance Python.pdf 英文原版 免费下载
- 【Scikit-Learn 中文文档】优化估计器的超参数
- Python 的 if __name__ == '__main__' 该如何理解
- hadoop-mapreduce原理篇
- splay的总结
- 游戏更新维护serverlist服务器列表替换python脚本
- Expert SQL Server in-Memory OLTP.pdf 英文原版 免费下载