题目大意

解题思路

对非法串构ac自动机,对于l较小的情况,设f[i][j]表示长度为i,在ac自动机上j点的方案数,直接dp即可。

对于加入串len<=2的情况,对于每个j拆成两个点矩阵快速幂即可。

code

#include<set>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LD double
#define LL long long
#define ULL unsigned long long
#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a>b)?a:b)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=100+9,mm=4*1e5+9,mo=1e9+7,inf=1e9;
int n,m,l,pon,tag[mn],fail[mn],q[mn],map[mn][30],f[mn][mn],ans[209][209],mat[209][209],tmp[209][209];
char s1[mn][mn],s[mn];
void multansmat(){fo(i,0,2*pon+1)fo(j,0,2*pon+1)tmp[i][j]=0;fo(i,0,2*pon+1)fo(j,0,2*pon+1)if(ans[i][j])fo(k,0,2*pon+1)tmp[i][k]=(tmp[i][k]+1ll*ans[i][j]*mat[j][k])%mo;fo(i,0,2*pon+1)fo(j,0,2*pon+1)ans[i][j]=tmp[i][j];
}
void multmatmat(){fo(i,0,2*pon+1)fo(j,0,2*pon+1)tmp[i][j]=0;fo(i,0,2*pon+1)fo(j,0,2*pon+1)if(mat[i][j])fo(k,0,2*pon+1)tmp[i][k]=(tmp[i][k]+1ll*mat[i][j]*mat[j][k])%mo;fo(i,0,2*pon+1)fo(j,0,2*pon+1)mat[i][j]=tmp[i][j];
}
int main(){//freopen("sorcery.in","r",stdin);//freopen("sorcery.out","w",stdout);freopen("d.in","r",stdin);freopen("d.out","w",stdout);scanf("%d%d%d\n",&n,&m,&l);fo(i,1,n)scanf("%s\n",s1[i]+1);fo(cas,1,m){scanf("%s\n",s+1);int now=0,pre,len=strlen(s+1);fo(i,1,len)now=map[now][s[i]-'a']=(map[now][s[i]-'a'])?map[now][s[i]-'a']:++pon;tag[now]=1;}int ti=0;fo(i,0,25)if(map[0][i])q[++ti]=map[0][i];fo(i,1,pon){fo(j,0,25)if(map[q[i]][j]){int next=map[q[i]][j];fail[next]=fail[q[i]];while(fail[next]&&(!map[fail[next]][j]))tag[next]|=tag[fail[next]],fail[next]=fail[fail[next]];fail[next]=map[fail[next]][j];q[++ti]=next;tag[next]|=tag[q[i]];tag[next]|=tag[fail[next]];}}if(l<=100){f[0][0]=1;fo(i,0,l)fo(j,0,pon)if(f[i][j])fo(cas,1,n){int now=j,ok=!tag[j],len=strlen(s1[cas]+1);fo(k,1,len){while(now&&(!map[now][s1[cas][k]-'a']))now=fail[now];now=map[now][s1[cas][k]-'a'];if(tag[now]){ok=0;break;}}if(ok)f[i+len][now]=(f[i+len][now]+f[i][j])%mo;}int ans=0;fo(j,0,pon)ans=(ans+f[l][j])%mo;printf("%d",ans);}else{ans[1][pon+1]=1;fo(cas,1,n){int now,ok,len=strlen(s1[cas]+1);fo(i,0,pon)if(!tag[i]){now=i;ok=1;fo(j,1,len){while(now&&(!map[now][s1[cas][j]-'a']))now=fail[now];now=map[now][s1[cas][j]-'a'];if(tag[now]){ok=0;break;}}if(len==1)mat[i+pon+1][now+pon+1]+=ok;else mat[i][now+pon+1]+=ok;}}fo(i,0,pon)mat[i+pon+1][i]++;while(l){if(l&1)multansmat();multmatmat();l>>=1;}int anss=0;fo(j,0,pon)anss=(anss+ans[1][j+pon+1])%mo;printf("%d",anss);}return 0;
}

【jzoj5078】【GDOI2017第三轮模拟day2】【魔法咒语】【ac自动机】【矩阵快速幂】相关推荐

  1. L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛,ac自动机+矩阵快速幂 或 BM线性递推)

    描述 God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells hi ...

  2. POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]

    http://poj.org/problem?id=2778 题意:给一些只由ACGT组成的模式串,问有多少种长度为n且不含有给出的模式串的DNA序列. 自动机的状态转换可以看成一个有向图(有重边的) ...

  3. HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  4. HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...

  5. POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...

  6. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/           --by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  7. 【BZOJ4861】【BJOI2017】—魔法咒语(AC自动机+矩阵快速幂优化dp)

    传送门 当 l ≤ 100 l\le 100 l≤100时 显然的自动机上 d p dp dp就完了 当 l ≤ 1 e 8 l\le1e8 l≤1e8时直接 d p dp dp显然是不行的 但是发现 ...

  8. POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)

    距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...

  9. HDU -2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题目链接 思路 假设让求长度为LLL且不包含词根的个数,对所有的词根建acacac自动机,然后用矩阵MMM表示可转移状态,最后最快速幂即可. 如何求长度不超过LLL且不包含LLL且不包含词根的个数,可 ...

  10. POJ 2778 DNA Sequence (AC自动机+矩阵快速幂)

    题目链接 MMM个病毒串,求长度为NNN的不包含病毒的字符串种类数 思路 把所有的病毒串建ACACAC自动机,failfailfail指针指向的节点如果标记过(包含病毒串)当前也是不合法串 . 然后我 ...

最新文章

  1. 线上慢查询?试试这几个优化思路!
  2. CentOS 搭建svn服务器
  3. 跟我学大数据分析之四:“钱”去哪儿了?
  4. opencv java match_OpenCV模板匹配函数matchTemplate详解
  5. python socket.error: [Errno 48] Address already in use
  6. keep健身软件电脑版_电脑软件:优酷 (优化版)
  7. webservice 安全性 对外_WebService安全性的几种实现方法【身份识别】
  8. border 0px和border none的区别
  9. Linux之常用操作命令总结三
  10. 2035年进入现代化交通强国行列
  11. 云免停机卡免流服务器监控
  12. 打桩(Stubbing), Mocking 和服务虚拟化的差异
  13. 一个中东外贸业务员分享的干货
  14. 2016全球大数据战略版图剖析(7):跨基础设施/分析篇
  15. Rsutdio安装REmap包出现错误及解决办法
  16. 目标追踪——光流法optical flow
  17. java 不是内部或外部命令,也不是可运行程序
  18. php读取文件不存在,php上传的文件不存在
  19. 网易——奖学金、路灯
  20. 线下+线上双管齐下,订单管理系统助力餐饮业提升销量

热门文章

  1. 让你的Android开发效率提高10倍的开源工具库AndroidTools的使用
  2. 自学网络安全详细路线图来了
  3. sed -i 替换内容中有变量或特殊字符
  4. 【Algorithm】算法设计与分析(第二版)- 王红梅 - JAVA / C++实现:3.9 荷兰国旗问题
  5. php 飞信接口 2013,php飞信每日自动天气预报 v1.0
  6. CAD填充遇到的几个问题
  7. Matlab基本函数-exp函数
  8. CDO(Climate Data Operator)系列之安装
  9. java的字符串数组添加元素_java 数组中插入新的元素
  10. PS-CBP 聚苯乙烯修饰卡铂/NK-1受体抑制剂修饰卡铂/卡铂修饰碳载钌纳米颗粒