| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
最裸的AC自动机#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LIM 201
#define mo 100000
#define MAX 10001
#define cp freopen
#define ll long long
#define rep(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
char S[MAX];
int s[MAX][4],d[MAX];
int num=1,n,m,r[MAX],f[MAX];
vector<int> danger,pre[LIM];
struct trie
{
int t[4];
}T[MAX];
struct mat
{
int l1,l2;
ll a[LIM][LIM];
void print()
{
rep(i,1,l1)
{
rep(j,1,l2)
cout<<a[i][j]<<' ';
cout<<endl;
}
cout<<endl;
}
void clear()
{
memset(a,0,sizeof(a));
}
};
mat operator *(mat a,mat b)
{
mat c;
c.l1=a.l1,c.l2=b.l2;
rep(i,1,a.l1)
rep(j,1,b.l2)
{
ll ans=0;
rep(k,1,a.l2)
{
ans+=a.a[i][k]*b.a[k][j];
ans%=mo;
}
c.a[i][j]=ans;
}
return c;
}
void ac_ins(int vi,int *r)
{
int now=r[0];
if (!T[vi].t[now])
T[vi].t[now]=++num;
if (r[1]==-1)
danger.push_back(
T[vi].t[now]);
else
ac_ins(T[vi].t[now],r+1);
}
void init()
{
int c[500];
c['A']=0;
c['G']=1;
c['C']=2;
c['T']=3;
cin>>n>>m;
gets(S);
rep(i,1,n)
{
gets(S);
int L=strlen(S);
rep(i,0,L-1)
r[i]=c[S[i]];
r[L]=-1;
ac_ins(1,r);
}
}
void ac_build()
{
f[1]=1;
queue<int> Q;
rep(i,0,3)
if (T[1].t[i])
{
Q.push(T[1].t[i]);
f[T[1].t[i]]=1;
pre[1].push_back(T[1].t[i]);
}
while (!Q.empty())
{
int h=Q.front();
Q.pop();
rep(i,0,3)
{
if (!T[h].t[i])
continue;
Q.push(T[h].t[i]);
int p=f[h];
while (p!=1&&!T[p].t[i])
p=f[p];
f[T[h].t[i]]=max(1,T[p].t[i]);
pre[max(1,T[p].t[i])].push_back(
T[h].t[i]);
}
}
}
int dfa(int vi,int j)
{
if (T[vi].t[j])
s[vi][j]=T[vi].t[j];
if (s[vi][j]==-1&&vi==1)
s[vi][j]=1;
if (s[vi][j]!=-1)
return s[vi][j];
s[vi][j]=dfa(f[vi],j);
return s[vi][j];
}
void ac_dfa()
{
memset(s,-1,sizeof(s));
rep(i,1,num)
rep(j,0,3)
s[i][j]=dfa(i,j);
}
void dfs(int vi)
{
// cout<<vi<<endl;
if (d[vi])
return;
d[vi]=1;
rep(i,0,int(pre[vi].size()-1))
dfs(pre[vi][i]);
}
void ac_danger()
{
rep(i,0,int(danger.size()-1))
dfs(danger[i]);
}
void ac_calc()
{
mat a,b;
a.clear();
b.clear();
a.l1=1,a.l2=num;
a.a[1][1]=1;
b.l1=b.l2=num;
rep(i,1,num)
{
if (d[i])
continue;
rep(j,0,3)
{
if (d[s[i][j]])
continue;
b.a[i][s[i][j]]++;
}
}
// b.print();
while (m)
{
if (m%2==1)
a=a*b;
b=b*b;
m/=2;
}
ll ans=0;
rep(i,1,num)
ans+=a.a[1][i],ans%=mo;
cout<<ans<<endl;
}
void solve()
{
ac_build();
ac_dfa();
ac_danger();
ac_calc();
}
void work()
{
init();
solve();
}
int main()
{
cp("1.in","r",stdin);
cp("1.out","w",stdout);
work();
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator