P3715 [BJOI2017]魔法咒语

用基本词汇组成\(L\)长度的单词,其中不能包含禁忌词汇

用禁忌词汇建强大的\(tire\)图

解决:

分类讨论,\(L<=100\)用普通dp暴力在\(tire\)图上用基本词汇跑,不能包含禁忌词汇

显然,\(L<=10^8\)肯定会超时的,注意到基本词汇的长度\(<=2\),矩阵优化一下

构造矩阵是一个难点,左边的矩阵两部分,我们要把\(dp_{i-2}与dp_{i-1}\)矩乘后达到\(dp_{i-1}与dp_{i}\)

右边的矩阵四部分

\((1)空 (2)len=2\)

$(3)单位矩阵(4)len=1 $

构造到此为止 直接快速幂就好了

My complete code

#include<bits/stdc++.h>
#include<queue>
using namespace std;
typedef long long LL;
const LL maxn=1010;
const LL MOD=1e9+7;
LL n,m,L,nod=1,ans;
LL son[maxn][30],end[maxn],fail[maxn],len[maxn],dp[maxn][maxn];
char ji[maxn][maxn];
inline void Insert(char *s){
LL l=strlen(s),now=1;
for(LL i=0;i<l;++i){
LL c=s[i]-'a';
if(!son[now][c])
son[now][c]=++nod;
now=son[now][c];
}
end[now]=true;
}
inline void Fbuild(){
queue<LL> que;
for(LL i=0;i<26;++i)
if(son[1][i]){
que.push(son[1][i]);
fail[son[1][i]]=1;
}else
son[1][i]=1;
while(que.size()){
LL u=que.front(); que.pop();
for(LL i=0;i<26;++i){
LL v=son[u][i];
if(v){
fail[v]=son[fail[u]][i];
que.push(v);
end[v]|=end[fail[v]];
}else
son[u][i]=son[fail[u]][i];
}
}
}
struct mat{
LL m[300][300];
}a,b,r;
inline LL Go(LL now,LL c){
return (end[son[now][c]])?-1:son[now][c];
}
inline mat Mul(const mat &x,const mat &y){
mat res;
memset(res.m,0,sizeof(res.m));
for(LL i=1;i<=2*nod;++i)
for(LL j=1;j<=2*nod;++j)
for(LL k=1;k<=2*nod;++k)
res.m[i][j]=(res.m[i][j]+x.m[i][k]*y.m[k][j]%MOD)%MOD;
return res;
}
inline void Pow(LL mi){
while(mi){
if(mi&1)
r=Mul(r,b);
b=Mul(b,b);
mi>>=1;
}
}
int main(){
scanf("%lld%lld%lld",&n,&m,&L);
for(LL i=1;i<=n;++i){
scanf(" %s",ji[i]);
len[i]=strlen(ji[i]);
}
for(LL i=1;i<=m;++i){
char s[maxn];
scanf(" %s",s);
Insert(s);
}
Fbuild();
if(L<=100){
dp[0][1]=1;
for(LL i=0;i<L;++i)
for(LL j=1;j<=nod;++j){
if(!dp[i][j])
continue;
for(LL k=1;k<=n;++k){//沿着基本串走
if(i+len[k]>L)
continue;
LL now=j;
for(LL q=0;q<len[k]&&now!=-1;++q)
now=Go(now,ji[k][q]-'a');
if(now!=-1)
dp[i+len[k]][now]=(dp[i+len[k]][now]+dp[i][j])%MOD;
}
}
for(LL i=1;i<=nod;++i)
ans=(ans+dp[L][i])%MOD;
printf("%lld",ans);
return 0;
} a.m[1][1+nod]=1;
for(LL i=1;i<=nod;++i)
b.m[i+nod][i]=1;
for(LL i=1;i<=nod;++i)
for(LL j=1;j<=n;++j){
if(len[j]!=1)
continue;
LL now=i;
if(end[now])
continue;
now=Go(now,ji[j][0]-'a');
if(now!=-1)
++b.m[nod+i][nod+now];
}
for(LL i=1;i<=nod;++i)
for(LL j=1;j<=n;++j){
if(len[j]!=2)
continue;
LL now=i;
if(end[now])
continue;
now=Go(now,ji[j][0]-'a');
if(now==-1)
continue;
now=Go(now,ji[j][1]-'a');
if(now!=-1)
++b.m[i][nod+now];
}
for(LL i=1;i<=2*nod;++i)
r.m[i][i]=1;
Pow(L);
a=Mul(a,r);
for(LL i=1;i<=nod;++i)
ans=(ans+a.m[1][nod+i])%MOD;
printf("%lld",ans);
return 0;
}

P3715 [BJOI2017]魔法咒语的更多相关文章

  1. bzoj4861 / P3715 [BJOI2017]魔法咒语

    P3715 [BJOI2017]魔法咒语 AC自动机+dp+矩阵乘法 常规思路是按基本串建立AC自动机 然鹅这题是按禁忌串建立AC自动机 对后缀是禁忌的点以及它的失配点做上标记$(a[i].ed)$, ...

  2. [BJOI2017]魔法咒语 --- AC自动机 + 矩阵优化

    bzoj 4860   LOJ2180   洛谷P3175 [BJOI2017]魔法咒语 题目描述: Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后,Chandra 就显示出对火元素无 ...

  3. Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂)

    Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂) 题目链接 题解: 多串匹配问题,很容易想到是AC自动机 先构建忌讳词语的AC自动机,构建时顺便记录一下这个点以及它的所有后 ...

  4. [BZOJ4861][BJOI2017]魔法咒语(AC自动机+矩阵优化DP)

    4861: [Beijing2017]魔法咒语 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 217  Solved: 105[Submit][Sta ...

  5. 【[BJOI2017]魔法咒语】

    矩阵乘法+\(AC\)自动机 是道很不错的题了 首先是前六十分,就是一个\(AC\)自动机上的套路\(dp\),设\(dp[i][j]\)表示匹配出的长度为\(i\)在自动机上位置为\(j\)的方案数 ...

  6. [BJOI2017]魔法咒语

    Description Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后, Chandra 就显示出对火元素无与伦比的亲和力,轻而易举地学会种种晦涩难解的法术.这也多亏 Chandra ...

  7. AHOI2018训练日程(3.10~4.12)

    (总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...

  8. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  9. 【题解】AC自动机题解合集

    最近貌似大家都在搞字符串?很长一段时间都没有写博客了……还是补一补坑吧. 感觉AC自动机真的非常优美了,通过在trie树上建立fail指针可以轻松解决多模匹配的问题.实际上在AC自动机上的匹配可以看做 ...

随机推荐

  1. EasyMvc入门教程-基本控件说明(11)菜单导航

    基本上,是个网站就会有菜单导航,目前流行的菜单是不是这样样子的? 似乎是bootstrap引领的风格,我们就用EasyMvc实现吧,上代码: @{ var data = new List<Men ...

  2. HDU 5402 Travelling Salesman Problem(多校9 模拟)

    题目链接:pid=5402">http://acm.hdu.edu.cn/showproblem.php?pid=5402 题意:给出一个n×m的矩阵,位置(i.j)有一个非负权值. ...

  3. 2016.6.20 eclipse安装完毕后打开失败,显示a JDK or a JRE must be avaliable in order to run Eclispe

    下载完成后,点击eclipse.exe,跳出如下错误. 按照百度的方法,修改了一下eclispe的配置文件,不仅没解决问题,结果跳出另一个新的错误: Failed to load the JNI sh ...

  4. c#课程设计---猜猜看游戏

    1:游戏要求 1. 随机显示 一个名字 与 若干张相片(如3张).选择正确的相片. 2. 记录老师对每一个学生的认识概率P.并依据认识概率,确定"猜猜看"游戏中学生出现的频率. 认 ...

  5. HDFS怎样检測并删除多余副本块

    前言 在HDFS中,每时每刻都在进行着大量block块的创建和删除操作,这些庞大的block块构建起了这套复杂的分布式系统.普通block的读写删除操作一般人都或多或少了解过一些,可是过量的副本清理机 ...

  6. VM tools安装错误The path &quot;&quot; is not a valid path to the xx generic kernel headers.

    在网上搜索非常多解决方式.并不适用于我的问题,最后通过下面步骤解决: 1. 更新软件源(防止build-essential不能 安装),然后安装build-essential和linu-headers ...

  7. 双十一前4小时,CentOS 6.5server启动错误排查

    11月10日晚上8点多.眼看要到双十一了... 但我要说的这段经历却和双十一毫无关系.哈哈. 这天准备向CentOS6.5server的svn上传一些文件,结果开机启动时,却出现了以下的界面: 这是肿 ...

  8. java 开发环境安装

    一.在mac上安装jdk 1. 下载Mac版本的JDK并安装      http://www.oracle.com/technetwork/java/javase/downloads/index.ht ...

  9. Uboot的串口下载文件命令:loads / loadb / loady

    1. loads loads [ off ] 通过串口,下载S-Rec文件到off位置 loads命令可以通过串口线下载S-Record格式文件. 2. loadb loadb [ off ] [ b ...

  10. Tomcat 7.0 servlet @WebServlet

    在使用tomcat7.0+eclipse j2ee时,新建Dynamic Web Project时, 会让选择是否生成web.xml.无论选择与否,此时新建一个servlet, 可以不在web.xml ...