hdu2243考研路茫茫——单词情结(ac+二分矩阵)

链接

跟2778差不多,解决了那道题这道也不成问题如果做过基本的矩阵问题。

数比较大,需要用unsigned longlong 就不需要mod了 溢出就相当于取余

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 30
 12 #define LL  unsigned __int64
 13 #define INF 0xfffffff
 14 #pragma comment(linker, "/STACK:1024000000,1024000000")
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int mn = 30;
 19 const int child_num = 26;
 20 struct Mat
 21 {
 22     LL mat[N][N];
 23 };
 24 Mat operator *(Mat a,Mat b)
 25 {
 26     Mat c;
 27     memset(c.mat,0,sizeof(c.mat));
 28     int i,j,k;
 29     for(k =0 ; k < mn ; k++)
 30     {
 31         for(i = 0 ; i < mn ;i++)
 32         {
 33             if(a.mat[i][k]==0) continue;//优化
 34             for(j = 0 ;j < mn ;j++)
 35             {
 36                 if(b.mat[k][j]==0) continue;//优化
 37                 c.mat[i][j] = c.mat[i][j]+(a.mat[i][k]*b.mat[k][j]);
 38             }
 39         }
 40     }
 41     return c;
 42 }
 43 Mat operator + (Mat a,Mat b)
 44 {
 45     Mat c;
 46     memset(c.mat,0,sizeof(c.mat));
 47     int i,j;
 48     for(i = 0 ; i < mn ;i++)
 49         for(j = 0 ;j < mn ;j++)
 50             c.mat[i][j] = a.mat[i][j]+b.mat[i][j];
 51     return c;
 52 }
 53 Mat operator ^(Mat a,int k)
 54 {
 55     Mat c;
 56     int i,j;
 57     for(i =0 ; i < mn ;i++)
 58         for(j = 0; j < mn ;j++)
 59         c.mat[i][j] = (i==j);
 60     for(; k ;k >>= 1)
 61     {
 62         if(k&1) c = c*a;
 63         a = a*a;
 64     }
 65     return c;
 66 }
 67 Mat cal(Mat x,int k)
 68 {
 69     if(k==1) return x;
 70     Mat c,cc;
 71     c = cal(x,k/2);
 72     cc = x^(k/2);
 73     c = c+cc*c;
 74     if(k&1)
 75     c = c+(x^k);
 76     return c;
 77 }
 78 LL ex_mod(int a,int k)
 79 {
 80     if(k==1) return a;
 81     LL t = ex_mod(a,k/2);
 82     t = t*t;
 83     if(k&1)
 84     t = t*a;
 85     return t;
 86 }
 87 LL solve(int a,int k)
 88 {
 89     if(k==1) return a;
 90     LL t = solve(a,k/2);
 91     t = t + ex_mod(a,k/2)*t;
 92     if(k&1) t = t+ex_mod(a,k);
 93     return t;
 94 }
 95 class AC
 96 {
 97     private:
 98     int ch[N][child_num];
 99     int Q[N];
100     int fail[N];
101     int val[N];
102     int sz;
103     int id[228];
104     public :
105     void init()
106     {
107         fail[0] = 0;
108         for(int i = 0 ; i < child_num ; i++)
109         id[i+'a'] = i;
110     }
111     void reset()
112     {
113         memset(val,0,sizeof(val));
114         memset(ch[0],0,sizeof(ch[0]));
115         memset(fail,0,sizeof(fail));
116         sz = 1;
117     }
118     void insert(char *a,int key)
119     {
120         int p = 0;
121         for(; *a ;a++)
122         {
123             int d = id[*a];
124             if(ch[p][d]==0)
125             {
126                 memset(ch[sz],0,sizeof(ch[sz]));
127                 ch[p][d] = sz++;
128             }
129             p = ch[p][d];
130         }
131         val[p] = key;
132     }
133     void construct()
134     {
135         int i;
136         int head =0, tail=0;
137         for(i = 0;i < child_num ;i++)
138         {
139             if(ch[0][i])
140             {
141                 fail[ch[0][i]] = 0;
142                 Q[tail++] = ch[0][i];
143             }
144         }
145         while(head!=tail)
146         {
147             int u = Q[head++];
148             val[u]|=val[fail[u]];
149             for(i= 0; i < child_num ; i++)
150             {
151                 if(ch[u][i])
152                 {
153                     fail[ch[u][i]] = ch[fail[u]][i];
154                     Q[tail++] = ch[u][i];
155                 }
156                 else ch[u][i] = ch[fail[u]][i];
157             }
158         }
159     }
160     void work(int n)
161     {
162         int i;
163         Mat x;
164         memset(x.mat,0,sizeof(x.mat));
165         for(i = 0 ; i < sz; i++)
166         {
167             for(int j = 0; j < child_num ; j++)
168             if(val[ch[i][j]]==0)
169             x.mat[i][ch[i][j]]++;
170         }
171         x = cal(x,n);
172         LL ans = 0;
173         for(i = 0 ; i < sz ; i++)
174         ans = ans+x.mat[0][i];
175         ans = solve(26,n)-ans;
176         cout<<ans<<endl;
177     }
178 }ac;
179 char vir[20];
180 int main()
181 {
182     int n,l,i;
183     ac.init();
184     while(scanf("%d%d",&n,&l)!=EOF)
185     {
186         ac.reset();
187         for(i = 1; i <= n; i++)
188         {
189             scanf("%s",vir);
190             ac.insert(vir,1);
191         }
192         ac.construct();
193         ac.work(l);
194     }
195     return 0;
196 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3735916.html