http://poj.org/problem?id=2778

有空再又一次做下,对状态图的理解非常重要

题解:

http://blog.csdn.net/morgan_xww/article/details/7834801

另外做了矩阵幂的模板:

//ac.sz是矩阵的大小
void mulmtr(long long x[MAXNODE][MAXNODE],long long y[MAXNODE][MAXNODE])//y=x*y
{
ll tmp[MAXNODE][MAXNODE];
for(int i=0;i<ac.sz;i++)
{
for(int j=0;j<ac.sz;j++)
{
tmp[i][j]=0;
for(int k=0;k<ac.sz;k++)
tmp[i][j] +=x[i][k]*y[k][j];
tmp[i][j] %=MOD;
}
}
for(int i=0;i<ac.sz;i++)
for(int j=0;j<ac.sz;j++)
y[i][j]=tmp[i][j];
}
void Mtrmi(ll mtr[MAXNODE][MAXNODE],int n)
{
for(int i=0;i<ac.sz;i++)
{
for(int j=0;j<ac.sz;j++)
{
if(i == j)ans[i][j]=1;//E矩阵
else ans[i][j]=0;
}
}
while(n)
{
if(n&1)
{
mulmtr(mtr,ans);
}
mulmtr(mtr,mtr);
n/=2;
}
}

代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <iostream>
using namespace std; #define ll long long const int MAXNODE = 15*15;
const int SSIZE = 2000000000+100;
const int MOD = 100000;
const int SIGMA_SIZE = 4;
const int SIZE = 20; ll mtr[MAXNODE][MAXNODE];
ll ans[MAXNODE][MAXNODE];
int danger[MAXNODE]; struct AC
{
int f[MAXNODE];
int val[MAXNODE];
int last[MAXNODE];
int cnt[MAXNODE];
int ch[MAXNODE][SIGMA_SIZE];
int sz; void init()
{
memset(ch[0],0,sizeof(ch[0]));
memset(cnt,0,sizeof(cnt));
f[0]=0;///////////
sz=1;
} inline int idx(char x)
{
if(x == 'A')return 0;
if(x == 'T')return 1;
if(x == 'C')return 2;
if(x == 'G')return 3;
} void insert(char *s, int v)
{
int n=strlen(s),u=0;
for(int i=0;i<n;i++)
{
int id= idx(s[i]);
if(!ch[u][id])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][id]=sz++;
}
u=ch[u][id];
}
val[u]=v;
danger[u]=1;////////
} void getfail()
{
queue<int>q;
f[0]=0;
for(int c=0;c<SIGMA_SIZE;c++)
{
int u=ch[0][c];
if(u)
{
q.push(u);
f[u]=0;
last[u]=0;
}
}
while(!q.empty())
{
int r=q.front();q.pop();
for(int c=0;c<SIGMA_SIZE;c++)
{
int u=ch[r][c];
//if(!u)continue;////////
if(!u)
{
ch[r][c]=ch[f[r]][c];//////
continue;
}
q.push(u);
int v=f[r];
while(v &&!ch[v][c])v=f[v];
f[u]=ch[v][c];
//last[u]=val[f[u]]?f[u]:last[f[u]];
danger[u] |= danger[f[u]];
}
}
}
};
void init()
{
memset(mtr,0,sizeof(mtr));
memset(danger,0,sizeof(danger));
} AC ac; char str[SIZE]; void mulmtr(long long x[MAXNODE][MAXNODE],long long y[MAXNODE][MAXNODE])//y=x*y
{
ll tmp[MAXNODE][MAXNODE];
for(int i=0;i<ac.sz;i++)
{
for(int j=0;j<ac.sz;j++)
{
tmp[i][j]=0;
for(int k=0;k<ac.sz;k++)
tmp[i][j] +=x[i][k]*y[k][j];
tmp[i][j] %=MOD;
}
}
for(int i=0;i<ac.sz;i++)
for(int j=0;j<ac.sz;j++)
y[i][j]=tmp[i][j];
}
void Mtrmi(ll mtr[MAXNODE][MAXNODE],int n)
{
for(int i=0;i<ac.sz;i++)
{
for(int j=0;j<ac.sz;j++)
{
if(i == j)ans[i][j]=1;//E矩阵
else ans[i][j]=0;
}
}
while(n)
{
if(n&1)
{
mulmtr(mtr,ans);
}
mulmtr(mtr,mtr);
n/=2;
}
} int main()
{
//freopen("poj2788.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&m,&n))
{
init();
ac.init();
for(int i=1;i<=m;i++)
{
scanf("%s",str);
ac.insert(str,i);
}
ac.getfail();
for(int i=0;i<ac.sz;i++)
if(!danger[i])
for(int j=0;j<4;j++)
if(!danger[ac.ch[i][j]])
{
mtr[i][ac.ch[i][j]]++;
} Mtrmi(mtr,n);
/////////////////////////////////
/* for(int i=0;i<ac.sz;i++)
{
for(int j=0;j<ac.sz;j++)
printf("%lld|%lld ",mtr[i][j],ans[i][j]);
putchar('\n');
}*/
///////////////////////
for(int i=1;i<ac.sz;i++)
ans[0][0]+=ans[0][i]%MOD;
printf("%I64d\n",ans[0][0]%MOD);
}
return 0;
}

POJ 2778 AC自己主动机+矩阵幂 不错的题的更多相关文章

  1. poj 2778 AC自己主动机 + 矩阵高速幂

    // poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...

  2. Hdu 2243 考研路茫茫——单词情结 (AC自己主动机+矩阵)

    哎哟喂.中文题. . .不说题意了. 首先做过POJ 2778能够知道AC自己主动机是能够求出长度为L的串中不含病毒串的数量的. POJ 2778的大概思路就是先用全部给的病毒串建一个AC自己主动机. ...

  3. hdu 2243 考研绝望——复杂的文字(AC自己主动机+矩阵高速功率)

    pid=2243" target="_blank" style="">题目链接:hdu 2243 考研路茫茫--单词情结 题目大意:略. 解题思 ...

  4. Hdu 3962 Microgene (AC自己主动机+矩阵)

    标题效果: 构造一个字符串,使得有两个和两个以上的目标串.长短L这一系列有多少串都. IDEAS: 只有全款减有1一些字符串,没有目标就是答案. 假定数据是非常小的,够用dp解.dp[i][j][k] ...

  5. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  6. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)

    题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...

  7. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  8. poj 1699 Best Sequence(AC自己主动机+如压力DP)

    id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...

  9. [POJ 1204]Word Puzzles(Trie树暴搜&amp;AC自己主动机)

    Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...

随机推荐

  1. MSSQL - 备份和还原数据库

    SQL语句备份和还原数据库:http://blog.csdn.net/liuhelong/article/details/3335687 1.MSSQL - SqlServer:此数据库处于单用户模式 ...

  2. USB基础简介

    一.USB2.0 Universal Serial Bus (通用串行总线)  符合USB总线数据通信要求的通信协议 1.意义 1.易用(热插拔.即插即用) 2.易扩充(USBHub可同时操作127个 ...

  3. UVA10006 - Carmichael Numbers

    题目链接:UVA10006 本来想直接打素数表,然后根据素数表来判断,结果一直超时,后来把素数表去掉,再在for循环中加判断才勉强过了. Some numbers that are not prime ...

  4. 跟我一起写 Makefile(一)

    跟我一起写 Makefile  陈皓 概述—— 什么是makefile?也许非常多Winodws的程序猿都不知道这个东西,由于那些Windows的IDE都为你做了这个工作,但我认为要作一个好的和pro ...

  5. 09-使用for循环输出空心菱形(循环)

    /** * 使用for循环输出空心菱形 * */ public class Test7 { public static void main(String[] args) { for (int i = ...

  6. 8天玩转并行开发——第二天 Task的使用

    原文 8天玩转并行开发——第二天 Task的使用 在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于 “任务的编程模型”所冲击, ...

  7. hive udaf 用maven打包运行create temporary function 时报错

    用maven打包写好的jar,在放到hive中作暂时函数时报错. 错误信息例如以下: hive> create temporary function maxvalue as "com. ...

  8. Canny边缘检測算法原理及其VC实现具体解释(一)

    图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般能够看作是一个阶跃,既从一个灰度值在非常小的缓冲区域内急剧变化到还有一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图 ...

  9. Sencha Touch 2 在MAC下详细的开发流程

    在不久的将来我相信Web App会流行的非常广, 能看到未来才能主宰未来.对于我们开发人员来说我觉得想成就一件伟大的事情,需要过硬的技术和好的想法,再加上决不放弃的精神,一定可以成功的. 以下在Mac ...

  10. 如果一个Object对象可能是数组那么如何对其进行迭代

    需求:一个方法传入的参数是Object类型(假设对象为“items”,使用Object类型也是为了使用多态而增加方法复用性),但已知这个Object对象可能是基本类型数组,也可能是对象数组,如何将这个 ...