还有5天省选才开始点字符串这棵技能树是不是太晚了点...

题目の传送门

AC自动机不想讲了QAQ.其实很久以前是学过然后打过板子的, 但也仅限于打过板子了~

之前莫名其妙学了一个指针版的但是好像不能用循环遍历fail好像就啥也干不了于是改成了数组...)

其实就是Trie树上挂fail指针... 然后可以完成多串的kmp的样子...

直接看题吧. 题目大意: 求长度为\(L\)的,包含给定的\(n\)个短串中的至少一个的字符串的数量.

考虑补集转化, 考虑含这些短串的字符串的数量. 然后用所有长度为\(L\)的字符串(\(26^L\))的数量减掉就行了.

然后建立AC自动机, 对于不存在的节点我们就直接让它指向根就可以了.

令\(f[i][j]\)表示在trie树上从\(i\)走一步到\(j\)不经过有isend标记的节点的方案数, 我们遍历AC自动机就可以求出这个矩阵(算是临接矩阵咯~).

然后根据临接矩阵的特点, 我们求出\(f^L[i][j]\)就是从\(i\)开始走\(L\)步到\(j\)时合法的方案数.

然后我们最后要求的数量就是\(ans=\sum_{i=1}^tf[root][i]\), 其中\(t\)表示Trie树上的节点数, 最后我们用\(26^L-ans\)即可.

有一个优化就是如果一个点的fail指针指向了一个有isend标记的节点, 那这个点也是不可达的(由fail指针的定义显然), 我们就也把它贴上isend标记即可.

下面就是隆重登场的1A代码:

其实我的spoj账号因为之前测试自动提交脚本的缘故已经惨不忍睹了..然而一大部分都已经被我disqualify掉了2333~

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=66;
const int p=10007;
char c[10];
int ch[N][26],fail[N],tot;
bool isend[N];
struct mat{int ma[N][N];}a;
inline void init(){
memset(ch,0,sizeof ch); tot=0;
memset(fail,0,sizeof fail);
memset(isend,0,sizeof isend);
memset(a.ma,0,sizeof a.ma);
}
inline void inser(char* s){
int len=strlen(s),now=0;
for(int i=0;i<len;++i){
int k=s[i]-'A';
if(!ch[now][k]) ch[now][k]=++tot;
now=ch[now][k];
} isend[now]=1;
}
inline void make_fail(){
queue<int> q;
for(int i=0;i<26;++i)
if(ch[0][i]) q.push(ch[0][i]),fail[ch[0][i]]=0;
while(!q.empty()){
int now=q.front(); q.pop();
if(isend[fail[now]]) isend[now]=1;
for(int i=0;i<26;++i){
if(ch[now][i]) fail[ch[now][i]]=ch[fail[now]][i],q.push(ch[now][i]);
else ch[now][i]=ch[fail[now]][i];
}
}
}
inline void make_mat(){
for(int i=0;i<=tot;++i)
for(int j=0;j<26;++j)
if(!isend[ch[i][j]])
++a.ma[i][ch[i][j]];
}
mat mat_mul(mat a,mat b){ mat c; int ans;
for(int i=0;i<=tot;++i)
for(int j=0;j<=tot;++j){
ans=0;
for(int k=0;k<=tot;++k){
ans+=a.ma[i][k]*b.ma[k][j];
while(ans>=p) ans-=p;
}
c.ma[i][j]=ans;
}
return c;
}
inline mat mat_pow(mat a,int b){ mat s=a;
for(--b;b;b>>=1,a=mat_mul(a,a))
if(b&1) s=mat_mul(s,a);
return s;
}
inline int qpow(int a,int b,int s=1){
for(a%=p;b;b>>=1,a=a*a%p)
if(b&1) s=s*a%p;
return s;
}
int main(){ int n,l;
while(scanf("%d%d",&n,&l)!=EOF){
init();
for(int i=0;i<n;++i){
scanf("%s",c); inser(c);
} make_fail();
make_mat();
mat b=mat_pow(a,l);
int ans=qpow(26,l);
for(int i=0;i<tot;++i){
ans-=b.ma[0][i];
if(ans<0) ans=ans+p;
}
printf("%d\n",ans%p);
}
}

【学术篇】SPOJ GEN Text Generator AC自动机+矩阵快速幂的更多相关文章

  1. POJ2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...

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

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

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

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

  4. POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17160   Accepted: 6616 Des ...

  5. poj2778 ac自动机+矩阵快速幂

    给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机 将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量 邻接矩阵https://we ...

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

    和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...

  7. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

  8. 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂

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

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

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

随机推荐

  1. mac OS 安装 Homebrew及常用命令

    Homebrew  是由国外大神 Max Howell 开发的一款包管理工具,类似Debian的apt,他可以安装任何你想安装的东西. 安装方法 命令行输入 /usr/bin/ruby -e &quo ...

  2. mysql基于GTIDS复制

    GTIDS的环境:一台master 192.168.200.111多个slave: 192.168.200.112 192.168.200.113 修改master服务器:[root@localhos ...

  3. erlang应用程序启动

    (1)erlang应用程序启动过程中,还可以分阶段启动.          在erlang应用程序的资源文件*.app可以定义分步骤启动.            *.app中的start_phase字 ...

  4. solaris系统动态查看swap的使用情况

    root@tt # root@tt # prstat  -aPlease wait... PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU ...

  5. 检测ip是否通过

    #!/bin/bashnetstat -an |grep "ESTABLISHED" |awk '{print $4}' |awk -F ':' '{print $1}' |sor ...

  6. java基础学习笔记一

    一.JAVA访问控制修饰符 用于控制类中成员的可见性 1.public(公有):在任何地方可以访问 2.protected(受保护的):子夫类(即使字父类不在同一包)和本包中可以访问 3.defaul ...

  7. 4K超清,2500万人在线,猫晚直播技术全解读

    摘要: 作为双11的必备节目,今年的猫晚通过优酷.浙江卫视.东方卫视进行了全程网络直播和电视直播,吸引了超过全球超过2.4亿人收看.猫晚期间,优酷基于阿里云最新的广播级高可靠直播方案,为近2500万的 ...

  8. java html生成图片html2canvas,Canvas2Image

    <html> <div id="pic" style="margin-left: 500px;position:fixed;opacity:0;&quo ...

  9. 重新学习MySQL数据库11:以Java的视角来聊聊SQL注入

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  10. MySQL教程和使用手册

    MySQL 教程 MySQL 教程.MySQL 安装.MySQL 管理.MySQL PHP 语法.MySQL 连接.MySQL 创建数据库.MySQL 删除数据库.MySQL 选择数据库.MySQL ...