POJ 1625

什么鬼,真的是有负数的吗?我在字符加上了128才过了。dp[i][j],经过i步到达j状态的路径数。转移很容易了,建个trie图就可以,由前一步可连通到和更新即可。

另外,要用到大数和AC自动机DP

  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 <map>
 10 #include <vector>
 11 #define LL  __int64
 12 using namespace std;
 13 
 14 const __int64 forward=100000000000000000LL;
 15 const int root=0;
 16 const int Maxn=550;
 17 int idx[600];
 18 struct BigNumber{
 19     LL num[16];
 20     void initial(){
 21         for(int i=0;i<15;i++)
 22         num[i]=0;
 23     }
 24 };
 25 BigNumber add_BigNumber(BigNumber a,BigNumber b){
 26     BigNumber c;
 27     c.initial();
 28     for(int i=0;i<15;i++){
 29         c.num[i]=c.num[i]+a.num[i]+b.num[i];
 30         c.num[i+1]=c.num[i]/forward;
 31         c.num[i]%=forward;
 32     }
 33     return c;
 34 }
 35 BigNumber dp[510][55];
 36 struct Node{
 37     bool tag;
 38     int next[55];
 39     int fail;
 40     void initial(){
 41         tag=false;
 42         memset(next,-1,sizeof(next));
 43         fail=-1;
 44     }
 45 };
 46 int que[Maxn],head,tail,tot;
 47 Node trie[Maxn];
 48 int dictsize,step;
 49 char str[60];
 50 
 51 void build_ac(){
 52     head=tail=0;
 53     que[tail++]=root;
 54     int tmp,p;
 55     while(head!=tail){
 56         tmp=que[head++];
 57         p=-1;
 58         for(int i=0;i<dictsize;i++){
 59             if(trie[tmp].next[i]!=-1){
 60                 if(tmp==root) trie[trie[tmp].next[i]].fail=root;
 61                 else{
 62                     p=trie[tmp].fail;
 63                     while(p!=-1){
 64                         if(trie[p].next[i]!=-1){
 65                             trie[trie[tmp].next[i]].fail=trie[p].next[i];
 66                             break;
 67                         }
 68                         p=trie[p].fail;
 69                     }
 70                     if(p==-1) trie[trie[tmp].next[i]].fail=root;
 71                 }
 72                 if(trie[trie[trie[tmp].next[i]].fail].tag)
 73                 trie[trie[tmp].next[i]].tag=true;
 74                 que[tail++]=trie[tmp].next[i];
 75             }
 76             else{    //trie[tmp].next[i]==-1
 77                 if(tmp==root) trie[tmp].next[i]=root;
 78                 else{
 79                     p=trie[tmp].fail;
 80                     while(p!=-1){
 81                         if(trie[p].next[i]!=-1){
 82                             trie[tmp].next[i]=trie[p].next[i];
 83                             break;
 84                         }
 85                         p=trie[p].fail;
 86                     }
 87                     if(p==-1)    trie[tmp].next[i]=root;
 88                 }
 89             }
 90         }
 91     }
 92 }
 93 
 94 int main(){
 95     int n,m,p,pt;
 96     cin>>n>>m>>p;
 97         for(int i=0;i<Maxn;i++) trie[i].initial();
 98         head=tail=tot=0;
 99         dictsize=n; step=m;
100         cin>>str;
101         for(int i=0;i<n;i++)
102         idx[str[i]+128]=i;
103     //    cout<<idx['a']<<endl;
104     //    cout<<idx['b']<<endl;
105         for(int i=0;i<p;i++){
106             cin>>str;
107             pt=root;int k=0;
108             int len=strlen(str);
109             while(k<len){
110                 if(trie[pt].next[idx[str[k]+128]]==-1) trie[pt].next[idx[str[k]+128]]=++tot;
111                 pt=trie[pt].next[idx[str[k]+128]];
112                 k++;
113             }
114             trie[pt].tag=true;
115         }
116 //        cout<<"YES"<<endl;
117         build_ac();
118 //        cout<<"YEA"<<endl;
119         for(int i=0;i<=tot;i++){
120             for(int j=0;j<=step;j++)
121             dp[i][j].initial();
122         }
123         dp[0][0].num[0]=1;
124         for(int k=0;k<step;k++){
125             for(int i=0;i<=tot;i++){
126                 if(!trie[i].tag){
127                     for(int j=0;j<dictsize;j++){
128                         if(!trie[trie[i].next[j]].tag)
129                         dp[trie[i].next[j]][k+1]=add_BigNumber(dp[trie[i].next[j]][k+1],dp[i][k]);
130                     }
131                 }
132             }
133         }
134         BigNumber ans;
135         ans.initial();
136     //    cout<<tot<<endl;
137         for(int i=0;i<=tot;i++){
138             if(!trie[i].tag){
139                 ans=add_BigNumber(ans,dp[i][step]);
140             }
141         }
142         bool flag=false;
143         for(int i=14;i>=1;i--)
144             if(ans.num[i]>0||flag){
145                 if(flag)
146                 printf("%017I64d",ans.num[i]);
147                 else
148                 printf("%I64d",ans.num[i]);
149                 flag=true;
150             }
151         if(flag) 
152         printf("%017I64d\n",ans.num[0]);
153         else{
154             printf("%I64d\n",ans.num[0]);
155         }
156     return 0;
157 }
View Code

 

posted @ 2015-03-03 00:15  chenjunjie1994  阅读(104)  评论(0编辑  收藏  举报