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

 

你可能感兴趣的:(HDU)