poj_2778_DNA Sequence(AC自动机+矩阵)
2016-07-27 13:16
471 查看
题意:
有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串
题解:
这题显然要用AC自动机,将模式串的AC自动机建好后,再构建矩阵,矩阵的含义是自动机中0~tot的节点走一步到0~tot的节点的方案数,然后要走n步,所以上一个矩阵快速幂就行了,在建AC自动机的时候要改变一下失败指针的指向,不存在的节点就指向当前节点的失败指针,这样就模拟了AC自动机的匹配过程,需要画图好好理解一下。
#include<cstdio> #include<cstring> #define mst(a,b) memset(a,b,sizeof(a)) #define F(i,a,b) for(int i=a;i<=b;i++) typedef long long ll; //-----------------------矩阵------------------------- const int mat_N=11*11+7,mo=1e5;//矩阵阶数,取膜 int N; struct mat{ ll c[mat_N][mat_N]; void init(){mst(c,0);} mat operator*(mat b){ mat M;M.init(); F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][j]=(M.c[i][j]+c[i][k]*b.c[k][j])%mo; return M; } mat operator+(mat b){ mat M; F(i,0,N)F(j,0,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo; return M; } mat operator^(ll k){ mat ans,M=(*this);ans.init(); F(i,0,N)ans.c[i][i]=1; while(k){if(k&1)ans=ans*M;k>>=1,M=M*M;} return ans; } }A; //-----------------------AC自动机----------------------- const int AC_N=11*11,tyn=4;//数量乘串长,类型数 struct AC_automation{ int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot; inline int getid(char x){ if(x=='A')return 0; if(x=='T')return 1; if(x=='G')return 2; if(x=='C')return 3; } void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));} void init(){tot=-1,fail[0]=-1,nw();} void insert(char *s,int x=0){ for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++) if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot; cnt[x]++;//串尾标记 } void build(int head=1,int tail=0){ for(Q[++tail]=0;head<=tail;){ for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){ if(x==0)fail[tr[0][i]]=0; else for(p=fail[x],fail[tr[x][i]]=0;~p;p=failView Code [p]) if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;} if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=1; Q[++tail]=tr[x][i]; }else if(x==0)tr[x][i]=0; else tr[x][i]=tr[fail[x]][i]; } } }AC; void build_mat() { A.init(); F(i,0,AC.tot)F(j,0,3)if(!AC.cnt[i]&&!AC.cnt[AC.tr[i][j]])A.c[i][AC.tr[i][j]]++; } int main() { ll n,m,ans;char buf[30]; while(~scanf("%lld%lld",&n,&m)) { AC.init(); F(i,1,n)scanf("%s",buf),AC.insert(buf); AC.build(),N=AC.tot,build_mat(),A=A^m,ans=0; F(i,0,AC.tot)ans+=A.c[0][i]; printf("%lld\n",ans%mo); } return 0; }
相关文章推荐
- 救济金发放 (The Dole QUEUE UVa 133)
- com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK assets/com.xx.xx
- mybatis_helloWorld_sequence图(3)
- UVA 540-Team Queue
- foreach (int i in d.Values) Console.Write(i);
- Umbraco中的ModelBuilder
- Runtime实例之-UIMenuController的使用
- PowerBuilder中按键处理使用的键盘码
- UITableView的其他设置
- iOS UICollectionViewCell拖拽移动(配Demo下载)
- luigi学习5-task详解
- mybatis result maps collection already contains value
- easyUI——控制datagrid的显示与隐藏
- EasyUI - 修改datagrid的content-type
- AS中build.gradle文件配置讲解
- 文件包含漏洞
- EasyUI——numberspinner的onChange事件
- iOS UI控件之----UIButton
- [LeetCode] 60. Permutation Sequence
- xib或者SB中设置边框颜色