POJ 2778(DNA Sequence-Fail指针+矩阵快速幂)
来源:互联网 发布:未注册双拼域名 编辑:程序博客网 时间:2024/06/11 13:10
在只有4个字母的字符集中,给你n个字符串(n*L<=100) ,求长度为m的且不包含前面任何一个序列的字符串个数(m<=2000000000)
建一个字典树,在上面加Fail指针
然后
最后建立邻接矩阵A,
预处理出字典树上的哪些节点会匹配字符串,删掉它们所在行、列
答案就是
#include<cstdio>#include<iostream>#include<functional>#include<vector>#include<cstring>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)) #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000)#define MAXN (100+10)#define MAXNode (100+10)#define Sigma_size (5)#define pb push_back long long mul(long long a,long long b){return (a*b)%F;}long long add(long long a,long long b){return (a+b)%F;}long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}typedef long long ll;void upd(ll &a,ll b){a=(a%F+b%F)%F;}ll pow2(ll a,ll b){ if (b==1) return a; if (b==0) return 1; ll p=pow2(a,b/2)%F; p=p*p%F; if (b&1) p=p*a%F; return p;}struct M { int n,m; ll a[MAXN][MAXN]; M(int _n=0){n=m=_n;MEM(a);} M(int _n,int _m){n=_n,m=_m;MEM(a);} void mem (int _n=0){n=m=_n;MEM(a);} void mem (int _n,int _m){n=_n,m=_m;MEM(a);} friend M operator*(M a,M b) { M c(a.n,b.m); For(k,a.m) For(i,a.n) For(j,b.m) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F; return c; } void make_I(int _n) { n=m=_n; MEM(a) For(i,n) a[i][i]=1; } }A;int n;ll m;class Trie{public: int ch[MAXNode][Sigma_size],fa[MAXNode]; int fail[MAXNode],go[MAXNode][Sigma_size]; int siz; bool tag[MAXNode]; void mem(){siz=0; MEM(tag) MEM(ch) MEM(fa) MEM(go) MEM(fail) } int idx(char c){return c=='A' ? 0 :c=='T' ? 1 :c=='C' ? 2 :3 ;} void insert(char *s) { int u=0,n=strlen(s); Rep(i,n) { int c=idx(s[i]); if (!ch[u][c]) { ++siz; MEM(ch[siz]); ch[u][c]=siz; fa[siz]=u; } u=ch[u][c]; } tag[u]=1; } int q[MAXNode+10]; void make_fail() { int Head=1,Tail=1; q[Head]=0; For(i,siz) fail[i]=0; while(Head<=Tail) { int u=q[Head]; Rep(c,4) { if (ch[u][c]) { q[++Tail]=ch[u][c]; if (u==0) fail[ch[u][c]]=0; else fail[ch[u][c]]=go[ fail[u] ][c]; go[u][c]=ch[u][c]; } else { go[u][c]=go[fail[u]][c]; } } Head++; }// For(i,siz) cout<<fail[i]<<" ";cout<<endl; For(i,Tail) { int now=q[i]; if (tag[fail[now]]) tag[now]=1; } int t=0; vector<int> Q; int h[MAXN]={0}; Rep(i,siz+1) { if (!tag[i]) Q.pb(i),h[i]=++t; } A.mem(t); For(i,t) { int now=Q[i-1]; Rep(j,4) { int v=go[now][j]; if (h[v]) A.a[i][h[v]]++; } } // For(i,t) {// For(j,t) cout<<A.a[i][j]<<' ';// cout<<endl;// } }}T;M pow2(M a,ll b) { M c;c.make_I(a.n); static bool a2[1000000]; int n=0;while (b) a2[++n]=b&1,b>>=1; For(i,n) { if (a2[i]) c=c*a; a=a*a; } return c; }char s[20];int main(){// freopen("poj2778.in","r",stdin);// freopen(".out","w",stdout); cin>>n>>m; T.mem(); For(i,n) { scanf("%s",s); T.insert(s); } T.make_fail(); A=pow2(A,m); ll ans=0; For(i,A.n) upd(ans,A.a[1][i]); cout<<ans<<endl; return 0;}
0 0
- POJ 2778(DNA Sequence-Fail指针+矩阵快速幂)
- POJ 2778:DNA Sequence(AC自动机+矩阵快速幂)
- poj 2778 DNA Sequence 【ac自动机 + dp + 矩阵快速幂】
- POJ 2778 DNA Sequence【AC自动机+矩阵快速幂】
- poj 2778 DNA Sequence(AC自动机+矩阵快速幂)
- [AC自动机+dp+矩阵快速幂] poj 2778 DNA Sequence
- poj 2778 DNA Sequence ac机+矩阵快速幂
- POJ 2778 - DNA Sequence (AC自动机 矩阵快速幂)
- POJ 2778DNA Sequence AC自动机 + 矩阵快速幂
- 【AC自动机+矩阵快速幂】 POJ 2778 DNA Sequence
- poj 2778 DNA Sequence AC自动机+矩阵快速幂
- poj 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence AC自动机+矩阵快速幂
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)
- poj--2778DNA Sequence+AC自动机+矩阵快速幂
- POJ 2778 DNA Sequence (AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence(AC自动机+矩阵快速幂)
- HDU 1226 超级密码| NYOJ 929 密码宝盒
- 1.9 String Rotation
- Codeforces Round #327 (Div. 2)E. Three States
- 51nod 1279 扔盘子 (二分查找的变形)
- java hashCode()方法和equals()方法
- POJ 2778(DNA Sequence-Fail指针+矩阵快速幂)
- Leetcode Regular Expression Matching
- VS2015生成程序在别人电脑无法运行 msvcp140.dll 0x000007b 问题处理方法
- DZ论坛全自动挂机回帖助手2015.10.25实用版
- 2.1 Remove Dups
- BufferedFileCopy
- Android 里button.requestFocus()后,要点击两次才生效
- Http 与 Socket 区别
- 通信协议——HTTP、TCP、UDP