考研路茫茫——单词情结 HDU - 2243 (ac自动机)

考研路茫茫——单词情结

 HDU - 2243 

题意:

和上一题基本差不多

比较坑的是,矩阵快速幂的时候m+1了,会爆int,所以要用long long

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define ull unsigned long long
  4 #define CLR(m,a) memset(m,a,sizeof(m))
  5 const int maxnode=35;
  6 const int sigma=26;
  7 
  8 struct Matrix
  9 {
 10     ull n,m[maxnode<<1][maxnode<<1];
 11     void init(ull sz)
 12     {
 13         n=sz;
 14         CLR(m,0);
 15     }
 16     Matrix(ull sz){init(sz);}
 17     void setE()
 18     {
 19         for(int i=0;i<n;i++) m[i][i]=1;
 20     }
 21     Matrix operator *(const Matrix &a)
 22     {
 23         Matrix ans(n);
 24         for(int k=0;k<n;k++)
 25             for(int i=0;i<n;i++)
 26                 for(int j=0;j<n;j++)
 27                     ans.m[i][j]=ans.m[i][j]+m[i][k]*a.m[k][j];
 28         return ans;
 29     }
 30 };
 31 
 32 struct AC
 33 {
 34     int ch[maxnode][sigma],f[maxnode];
 35     int match[maxnode];
 36     int sz;
 37 
 38     void init()
 39     {
 40         CLR(ch[0],0);
 41         CLR(match,0);
 42         sz=1;
 43     }
 44     int idx(char c){return c-'a';}
 45     void inser(char *s)
 46     {
 47         int u=0,n=strlen(s);
 48         for(int i=0;i<n;i++){
 49             int c=idx(s[i]);
 50             if(!ch[u][c]){
 51                 CLR(ch[sz],0);
 52                 ch[u][c]=sz++;
 53             }
 54             u=ch[u][c];
 55         }
 56         match[u]=1;
 57     }
 58     void getfail()
 59     {
 60         queue<int> q;
 61         f[0]=0;
 62         for(int c=0;c<sigma;c++){
 63             int u=ch[0][c];
 64             if(u){
 65                 q.push(u);
 66                 f[u]=0;
 67             }
 68         }
 69         while(!q.empty()){
 70             int r=q.front();
 71             q.pop();
 72             for(int c=0;c<sigma;c++){
 73                 int u=ch[r][c];
 74                 if(!u){ch[r][c]=ch[f[r]][c];continue;}
 75                 q.push(u);
 76                 int v=f[r];
 77                 while(v&&!ch[v][c]) v=f[v];
 78                 f[u]=ch[v][c];
 79                 match[u]|=match[f[u]];
 80             }
 81         }
 82     }
 83     ull solve(ull m)
 84     {
 85         int tot=sz*2;
 86         Matrix a(tot),b(tot);
 87         for(int i=0;i<sz;i++)
 88         for(int j=0;j<sigma;j++){
 89             if(match[i]||match[ch[i][j]]) continue;
 90             a.m[i][ch[i][j]]++;
 91         }
 92         for(int i=0;i<sz;i++) a.m[i][i+sz]=1;  //构造矩阵这里wa了几次。。。
 93         for(int i=sz;i<tot;i++) a.m[i][i]=1;
 94         b.setE();
 95         ull t=m;
 96         while(t){
 97             if(t&1) b=b*a;
 98             t>>=1;
 99             a=a*a;
100         }
101         ull ans1=0;
102         for(int i=sz;i<tot;i++)
103             ans1=ans1+b.m[0][i];
104         ans1--;
105 
106         Matrix c(2),d(2);
107         d.setE();
108         c.m[0][0]=26;c.m[0][1]=c.m[1][1]=1;
109         while(m){
110             if(m&1) d=d*c;
111             m>>=1;
112             c=c*c;
113         }
114         ull ans2=d.m[0][1]-1;
115         return ans2-ans1;
116     }
117 };
118 AC ac;
119 int main()
120 {
121     ull n,m;   
122     char s[10];
123     while(scanf("%llu%llu",&n,&m)!=EOF){
124         ac.init();
125         for(int i=0;i<n;i++){
126             scanf("%s",s);
127             ac.inser(s);
128         }
129         ac.getfail();
130         printf("%llu\n",ac.solve(m+1)); 
131     }
132 }
View Code

 

posted @ 2017-08-18 10:52  yijiull  阅读(169)  评论(0编辑  收藏  举报