bzoj4861 / P3715 [BJOI2017]魔法咒语
AC自动机+dp+矩阵乘法
常规思路是按基本串建立AC自动机
然鹅这题是按禁忌串建立AC自动机
对后缀是禁忌的点以及它的失配点做上标记$(a[i].ed)$,到时候不访问。
基本串转化为自动机上的边:设$p[j][i]$表示第$j$个节点加上第$i$个串会到的节点编号
在建好AC自动机后可以直接处理。
现在分类讨论(对,两份代码)
1.$L<=100,60pts$
直接在AC自动机上跑dp
设$f[j][i]$表示到点$j$长度为$i$的方案数
枚举基本串$1~k$,显然$f[p[j][k]][i+size[k]]+=f[j][i]$
$sz$表示AC自动机的节点数,则$ans=\sum_{i=0}^{sz}f[i][L]*[a[i].ed==0]$
2.基本词汇长度不超过$2,40pts$
开个$maxn*2$的矩阵,矩阵乘法瞎搞。
$f[i][L]=\sum_{j}f[j][l-1],j->i$
对于长度为2的情况,就开2倍的数组,用$i*2+1$暂时保存。
注意下标从0开始
(为啥我的常数这么大呢......)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define N 105
const int mod=1e9+;
int ans,sz,n,m,L,siz[N],f[N][N],p[N][N];
char q[N],s[N][N];
queue <int> h; struct node{int nxt[],f,ed;}a[];
void add(){
scanf("%s",q);
int len=strlen(q),u=;
for(int i=;i<len;++i){
if(!a[u].nxt[q[i]-'a'])
a[u].nxt[q[i]-'a']=++sz;
u=a[u].nxt[q[i]-'a'];
}a[u].ed=;
}
void acbuild(){
for(int i=;i<;++i) if(a[].nxt[i]) h.push(a[].nxt[i]);
while(!h.empty()){
int x=h.front();h.pop();
for(int i=;i<;++i){
int &to=a[x].nxt[i];
if(to){
a[to].f=a[a[x].f].nxt[i];
a[to].ed|=a[a[to].f].ed;
h.push(to);
}else to=a[a[x].f].nxt[i];
}
}
} struct mat{
int A[][];
mat(){memset(A,,sizeof(A));}
mat operator * (mat &tmp) const{
mat c;int w=sz<<|;
for(int i=;i<=w;++i)
for(int j=;j<=w;++j)
for(int k=;k<=w;++k)
c.A[i][j]=(c.A[i][j]+1ll*A[i][k]*tmp.A[k][j]%mod)%mod;
return c;
}
};
mat Pow(mat x,int y){
mat rs;
for(int i=;i<=sz;++i)
rs.A[i<<][i<<]=;
for(;y;y>>=,x=x*x)
if(y&) rs=rs*x;
return rs;
} void task1(){
f[][]=;
for(int i=;i<L;++i)
for(int j=;j<=sz;++j)
if(f[j][i])
for(int k=;k<=n;++k)
if(p[j][k]!=-&&i+siz[k]<=L)
f[p[j][k]][i+siz[k]]=(f[p[j][k]][i+siz[k]]+f[j][i])%mod;
for(int i=;i<=sz;++i) if(!a[i].ed) ans=(ans+f[i][L])%mod;
}
void task2(){
mat res;
for(int i=;i<=sz;++i){
for(int j=;j<=n;++j)
if(p[i][j]!=-){
if(siz[j]==) ++res.A[p[i][j]<<][i<<];
else ++res.A[p[i][j]<<][i<<|];
}
res.A[i<<|][i<<]=;
}res=Pow(res,L);
for(int i=;i<=sz;++i) if(!a[i].ed) ans=(ans+res.A[i<<][])%mod;
}
int main(){
memset(p,-,sizeof(p));
scanf("%d%d%d",&n,&m,&L);
for(int i=;i<=n;++i) scanf("%s",s[i]),siz[i]=strlen(s[i]);
for(int i=;i<=m;++i) add();
acbuild();
for(int i=;i<=n;++i)
for(int j=,u=;j<=sz;u=++j){
for(int k=;k<siz[i]&&!a[u].ed;++k)
u=a[u].nxt[s[i][k]-'a'];
if(!a[u].ed) p[j][i]=u;
}
if(L<=) task1();
else task2();
printf("%d",ans);
return ;
}
bzoj4861 / P3715 [BJOI2017]魔法咒语的更多相关文章
- P3715 [BJOI2017]魔法咒语
P3715 [BJOI2017]魔法咒语 用基本词汇组成\(L\)长度的单词,其中不能包含禁忌词汇 用禁忌词汇建强大的\(tire\)图 解决: 分类讨论,\(L<=100\)用普通dp暴力在\ ...
- [BJOI2017]魔法咒语 --- AC自动机 + 矩阵优化
bzoj 4860 LOJ2180 洛谷P3175 [BJOI2017]魔法咒语 题目描述: Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后,Chandra 就显示出对火元素无 ...
- Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂)
Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂) 题目链接 题解: 多串匹配问题,很容易想到是AC自动机 先构建忌讳词语的AC自动机,构建时顺便记录一下这个点以及它的所有后 ...
- 【BZOJ4861】[Beijing2017]魔法咒语 矩阵乘法+AC自动机+DP
[BZOJ4861][Beijing2017]魔法咒语 题意:别看BZ的题面了,去看LOJ的题面吧~ 题解:显然,数据范围明显的分成了两部分:一个是L很小,每个基本词汇长度未知:一个是L很大,每个基本 ...
- [BZOJ4861][BJOI2017]魔法咒语(AC自动机+矩阵优化DP)
4861: [Beijing2017]魔法咒语 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 217 Solved: 105[Submit][Sta ...
- 【[BJOI2017]魔法咒语】
矩阵乘法+\(AC\)自动机 是道很不错的题了 首先是前六十分,就是一个\(AC\)自动机上的套路\(dp\),设\(dp[i][j]\)表示匹配出的长度为\(i\)在自动机上位置为\(j\)的方案数 ...
- [BJOI2017]魔法咒语
Description Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后, Chandra 就显示出对火元素无与伦比的亲和力,轻而易举地学会种种晦涩难解的法术.这也多亏 Chandra ...
- 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题) ...
- AC 自动机学习笔记
虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...
随机推荐
- zabbix 配合钉钉群机器人(webhook) 报警
首先建钉钉群,添加一个自定义机器人拿到webhook zabbix添加一个报警媒介 搞一个shell脚本来启动Python脚本(直接用zabbix调Python脚本不行,不知道什么原因) vim di ...
- ASP.Net中的四种状态保持机制
每个人上网可多有过这样的情况,当我们登陆某个网站时,在登陆的旁边会有一个 "记住我" 的复选框,有的网站还会让用户选择记住我.这个记住我是怎么实现的呢? 其实就用利用的是cooki ...
- tcp_nopush高性能
nginx sendfile tcp_nopush tcp_nodelay参数解释
- 委托 匿名 lambda表达式
#region 委托 delegate int ACT(int a, int b); static void Main(string[] args) { ACT act = new ACT(add); ...
- ASP.Net Core 2.2 MVC入门到基本使用系列 (四)(转)
本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...
- vue中点击复制粘贴功能
1.下载clipboard.js cnpm install clipboard --save 2.引入,可以在mian.js中全局引入也可以在单个vue中引入 import Clipboard fro ...
- sqli-labs(十二)(union以及select的过滤)
第二十七关: 这关禁用了空格和select,空格还是可以使用()代替,select发现可以大小写绕过 输入?id=1'||extractvalue(1,concat(0x5c,(selEct(grou ...
- HDU 3306 Another kind of Fibonacci(矩阵+ll超时必须用int&输入必须取模&M必须是int类型)
Another kind of Fibonacci [题目链接]Another kind of Fibonacci [题目类型]矩阵+ll超时必须用int&输入必须取模&M必须是int ...
- Sublime text3 经常出现 “ There are no packages avaliable for installation” 解决方法
对应这个问题,一开始在度娘上找到很多答案,包括将json文件放在本地然后通过 package setting 更改的,发现其实不好使,原因未知. 后来测试了在hosts文件添加sublime text ...
- python拼接变量、字符串的3种方法
第一种,加号(“+”): print 'py'+'thon' # output python str = 'py' print str+'thon' # output python 第二种 ,空格: ...