题意,给出一些串,问m个字符组成的串不包含这些串的有多少种情况。
自动机加矩阵快速幂。
矩阵相乘就是第i行第j列的数就是前一个矩阵的第i行,与后一矩阵的第j列,要保证前一个矩阵的列数等于后一个矩阵的行数。
构造的时候,只要把那些通向结点或通向的点的fild指向结点的节点去掉,其他正常
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #include<queue> #include<map> using namespace std; const int maxa = 105; const int cha = 4; #define LL long long int n, m, k; map<char, int> mp; const int mod = 100000; struct Matrix{ int a[maxa][maxa]; Matrix(){ memset(a, 0, sizeof(a)); } Matrix operator *(const Matrix &b)const { Matrix ret; for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) { int tmp=(long long)a[i][k]*b.a[k][j]%mod; ret.a[i][j]=(ret.a[i][j]+tmp)%mod; } return ret; }/* Matrix operator *(const Matrix &b) const{ Matrix tmp; for(int i =0 ;i < n; i++){; for(int j = 0; j < n; j++){ for(int k = 0;k <n; k++){ LL lo = (LL) (tmp.a[i][j]) + (LL)(a[i][k]) *b.a[k][j]; lo %= mod; tmp.a[i][j] = lo; } } } return tmp; }*/ }; struct Tire{ int next[maxa][cha], fail[maxa], end[maxa]; int root, L; int newnode(){ for(int i = 0; i < cha; i++){ next[L][i] = -1; } end[L++] = 0; return L-1; } void init(){ L = 0; root = newnode(); } void insert(char buf[]){ int len = strlen(buf); int now = root; for(int i = 0; i < len; i++){ int x = mp[buf[i]]; if(next[now][x] == -1) next[now][x] = newnode(); now = next[now][x]; //printf("%d ", now); }//puts(""); end[now] ++; } void build(){ queue<int>Q; fail[root] = root; for(int i = 0; i < cha; i++){ if(next[root][i] == -1) next[root][i] = root; else{ fail[next[root][i]] = root; Q.push(next[root][i]); } } while(!Q.empty()){ int now = Q.front(); if(end[fail[now]]){ end[now] = 1; } Q.pop(); // end[now] |= end[fail[now]]; for(int i = 0; i < cha; i++){ if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; else{ fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); // printf("**%d %d\n",next[now][i],next[fail[now]][i]); } } } } Matrix make_Maxtrix(){ Matrix tmp; for(int i = 0; i < L; i++){ for(int k = 0; k < cha; k++){ if(!end[next[i][k]]){ tmp.a[i][next[i][k]] ++; } } } return tmp; } }; Matrix pow(Matrix a,int m) { Matrix ret;// = Matrix(a.n); for(int i = 0; i < n; i++) ret.a[i][i]=1; Matrix tmp=a; while(m) { if(m&1)ret=ret*tmp; tmp=tmp*tmp; m>>=1; } return ret; } char buf[1000005]; Tire ac; int main(){ mp[‘A‘] = 0; mp[‘T‘] = 1; mp[‘G‘] = 2; mp[‘C‘] = 3; int N, M; while(scanf("%d%d", &N, &M)!=EOF){ ac.init(); while(N--){ scanf("%s", buf); ac.insert(buf); } ac.build(); n = ac.L; Matrix a = ac.make_Maxtrix(); Matrix b = pow(a, M);; int ans =0 ; for(int i = 0; i < n ;i++){ ans += b.a[0][i]; ans %= mod; }printf("%d\n", ans); } } /* abcdefg bcdefg cdef de e ssaabcdefg */
时间: 2024-10-15 13:26:49