HDU 2243

//因为2^64次方不可能表示,直接定义unsigned __int64,可以自动截断。其他和POJ 2778差不多。
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <climits>
  6 #include <string.h>
  7 #include <queue>
  8 #include <cmath>
  9 #include <vector>
 10 #define LL unsigned __int64
 11 using namespace std;
 12 const int dictsize=26;
 13 const int root=0;
 14 const int QN=100;
 15 struct Node{
 16     int fail,next[dictsize];
 17     bool tag;
 18     void initial(){
 19         memset(next,-1,sizeof(next));
 20         tag=false,fail=-1;
 21     }
 22 };
 23 Node trie[50];
 24 int que[QN],head,tail,tot;
 25 struct Matrix{
 26     LL mat[95][95];
 27 }a,per,number;
 28 int n,l;
 29 char str[20];
 30 
 31 void Insert_trie(){
 32     int p=root,i=0,index;
 33     while(str[i]){
 34         index=str[i]-'a';
 35         if(trie[p].next[index]==-1){
 36             trie[p].next[index]=++tot;
 37         }
 38         p=trie[p].next[index];
 39         i++;
 40     }
 41     trie[p].tag=true;
 42 }
 43 
 44 void build_ac(){
 45     int p,tmp;
 46     que[tail++]=root;
 47     while(head!=tail){
 48         tmp=que[head++];
 49         p=-1;
 50         for(int i=0;i<dictsize;i++){
 51             if(trie[tmp].next[i]!=-1){
 52                 if(tmp==root) trie[trie[tmp].next[i]].fail=root;
 53                 else{
 54                     p=trie[tmp].fail;
 55                     while(p!=-1){
 56                         if(trie[p].next[i]!=-1){
 57                             trie[trie[tmp].next[i]].fail=trie[p].next[i];
 58                             break;
 59                         }
 60                         p=trie[p].fail;
 61                     }
 62                     if(p==-1) trie[trie[tmp].next[i]].fail=root;
 63                 }
 64                 if(trie[trie[trie[tmp].next[i]].fail].tag)
 65                 trie[trie[tmp].next[i]].tag=true;
 66                 que[tail++]=trie[tmp].next[i];
 67             }
 68             else{    //    tmp[tmp].next[i]==-1
 69                 if(tmp==root) trie[tmp].next[i]=root;
 70                 else{
 71                     p=trie[tmp].fail;
 72                     while(p!=-1){
 73                         if(trie[p].next[i]!=-1){
 74                             trie[tmp].next[i]=trie[p].next[i];
 75                             break;
 76                         }
 77                         p=trie[p].fail;
 78                     }
 79                     if(p==-1){
 80                         trie[tmp].next[i]=root;
 81                     }
 82                 }
 83             }
 84         }
 85     }
 86 }
 87 
 88 void build_map(){
 89     memset(a.mat,0,sizeof(a.mat));
 90     for(int i=0;i<=tot;i++){
 91         for(int j=0;j<dictsize;j++)
 92         if(!trie[i].tag&&!trie[trie[i].next[j]].tag)
 93         a.mat[i][trie[i].next[j]]++;
 94     }
 95     int tmp=2*tot+1;
 96     for(int i=0;i<=tmp;i++){
 97         for(int j=tot+1;j<=tmp;j++){
 98             if(i==j) a.mat[i][j]=1;
 99             else if(j-tot-1==i) a.mat[i][j]=1;
100         }
101     }
102     number.mat[0][0]=26,number.mat[0][1]=1;
103     number.mat[1][0]=0,number.mat[1][1]=1;
104 }
105 
106 Matrix Multi(Matrix a,Matrix b,int e){
107     Matrix c;
108     for(int i=0;i<=e;i++){
109         for(int j=0;j<=e;j++){
110             c.mat[i][j]=0;
111             for(int k=0;k<=e;k++)
112             c.mat[i][j]=(c.mat[i][j]+(a.mat[i][k]*b.mat[k][j]));
113         }
114     }
115     return c;
116 }
117 
118 Matrix multi(Matrix s,LL k,int e){
119 //    cout<<k<<endl;
120     Matrix ret=per,p=s;
121     while(k){
122         if(k&1) ret=Multi(ret,p,e);
123         k>>=1;
124         p=Multi(p,p,e);
125     }
126     return ret;
127 }
128 
129 int main(){
130     memset(per.mat,0,sizeof(per.mat));
131     for(int i=0;i<95;i++)
132     per.mat[i][i]=1LL;
133     while(scanf("%d%d",&n,&l)!=EOF){
134         for(int i=0;i<35;i++)
135         trie[i].initial();
136         tot=head=tail=0;
137         for(int i=1;i<=n;i++){
138             scanf("%s",str);
139             Insert_trie();
140         }
141         build_ac();
142         build_map();
143     //    cout<<tot<<endl;
144         Matrix n1=multi(number,(LL)l+1LL,1);
145         Matrix n2=multi(a,(LL)l+1LL,2*tot+1);
146         LL ans=n1.mat[0][1];
147 //        cout<<ans<<endl;
148 /*        for(int i=0;i<=2*tot+1;i++){
149         for(int j=0;j<=2*tot+1;j++)
150         cout<<a.mat[i][j]<<" ";
151         cout<<endl;
152         }*/
153         int tmp=2*tot+1;
154         for(int i=tot+1;i<=tmp;i++)
155         ans=(ans-n2.mat[0][i]);
156         printf("%I64u\n",ans);
157     }
158 }
View Code

 

posted @ 2015-03-02 16:59  chenjunjie1994  阅读(239)  评论(0编辑  收藏  举报