POJ 2778 AC自己主动机+矩阵幂 不错的题
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自己主动机+矩阵幂 不错的题的更多相关文章
- poj 2778 AC自己主动机 + 矩阵高速幂
// poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...
- Hdu 2243 考研路茫茫——单词情结 (AC自己主动机+矩阵)
哎哟喂.中文题. . .不说题意了. 首先做过POJ 2778能够知道AC自己主动机是能够求出长度为L的串中不含病毒串的数量的. POJ 2778的大概思路就是先用全部给的病毒串建一个AC自己主动机. ...
- hdu 2243 考研绝望——复杂的文字(AC自己主动机+矩阵高速功率)
pid=2243" target="_blank" style="">题目链接:hdu 2243 考研路茫茫--单词情结 题目大意:略. 解题思 ...
- Hdu 3962 Microgene (AC自己主动机+矩阵)
标题效果: 构造一个字符串,使得有两个和两个以上的目标串.长短L这一系列有多少串都. IDEAS: 只有全款减有1一些字符串,没有目标就是答案. 假定数据是非常小的,够用dp解.dp[i][j][k] ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)
题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...
- POJ 3691 & 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: ...
- poj 1699 Best Sequence(AC自己主动机+如压力DP)
id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...
- [POJ 1204]Word Puzzles(Trie树暴搜&AC自己主动机)
Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...
随机推荐
- 黑马day16 jquery&层次选择器
假设想通过DOM元素之间的层次关系来获取特定元素,比如后代元素,子元素,相邻元素,兄弟元素等,则须要使用层次选择器. 1 .ancestor descendant 使用方法: $("form ...
- spring+mybatis利用interceptor(plugin)兑现数据库读写分离
使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是"地位相当"的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这 ...
- Get started - UIkit documentation
Get started - UIkit documentation Get started Get familiar with the basic setup and structure of UIk ...
- 一个必用的javascript框架:underscore.js - wine的思考 - ITeye技术网站
AngularJS+JqueryMobile+PhoneGap 打造APP « Dogeek AngularJS+JqueryMobile+PhoneGap 打造APP
- php连接oracle及简单操作
使你的php支持oracle,按照以下步骤即可: 1.安装php环境,找一下appserv或者xampp,一键安装,很方便 2.把php的ext目录下的php_oci8.dll拷到system32目录 ...
- C++要点
以下的这些要点是对全部的C++程序猿都适用的.我之所以说它们是最重要的,是由于这些要点中提到的是你通常在C++书中或站点上无法找到的.如:指向成员的指针,这是很多资料中都不愿提到的地方, ...
- EasyUI - Messager消息框
全局设定: JavaScript代码: //设置按钮中的文字,默认是-ok/cancel ,可以任意设置文字,比如现在的-确认/取消 $.messager.defaults = { ok: '确认', ...
- QT中的pro文件的编写
原地址:http://blog.csdn.net/fjb2080/article/details/4833666 我们在编译QT的工程的时候,一般都会让qmake自动生成,但有时我们需要定制我们的工程 ...
- 基于visual Studio2013解决C语言竞赛题之1085相邻之和素数
题目 解决代码及点评 /************************************************************************/ /* ...
- android用shape画虚线,怎么也不显示
一直以为android的shape能画直线.虚线.矩形,圆形等.画直线也就算了.用一个view设一下高度和颜色,就能够出来一条直线了.所以说这个对我来说常常不用,圆形是能够,看看我应用里的消息提 ...