hdu 2243(AC 로봇 + dp + 매트릭스 신속 멱)

5860 단어
징그럽다
/*
 * =====================================================================================
 *
 *       Filename:  2243.cpp
 *        Version:  1.0
 *        Created:  2013-08-25 21:28:30
 *       Revision:  none
 *       Compiler:  GNU C++
 *
 *      Just like you,wait you forever~~
 *
 * =====================================================================================
 */
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define PB              push_back
#define SIZE(x)         (int)x.size()
#define clr(x,y)        memset(x,y,sizeof(x))
#define MP(x,y)         make_pair(x,y)
#define RS(n)           scanf ("%s", n)
#define ALL(t)          (t).begin(),(t).end()
#define FOR(i,n,m)      for (int i = n; i <= m; i ++)
#define ROF(i,n,m)      for (int i = n; i >= m; i --)
#define IT              iterator
#define FF              first
#define SS              second

typedef long long               ll;
typedef unsigned int            uint;
typedef unsigned long long      ull;
typedef vector<int>             vint;
typedef vector<string>          vstring;
typedef pair<int, int>          PII;

void RI (int& x){
        x = 0;
        char c = getchar ();
        while (c == ' '||c == '
') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x; } void RII (int& x, int& y){RI (x), RI (y);} void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);} /**************************************END define***************************************/ const ll mod = 1e9+7; const ll LINF = 1e18; const int INF = 1e9; const double EPS = 1e-8; const int NODE = 35, CHD = 26; int sz, fail[NODE], chd[NODE][CHD], val[NODE], code[256], len; struct Mat{ ull a[NODE][NODE]; void initzero (){ clr (a, 0); } void initunit (){ FOR (i, 0, len-1){ FOR (j, 0, len-1){ a[i][j] = (i==j?1:0); } } } friend Mat operator * (Mat a, Mat b){ Mat ans; ans.initzero (); FOR (i, 0, len-1){ FOR (j, 0, len-1){ FOR (k, 0, len-1){ ans.a[i][j] += a.a[i][k]*b.a[k][j]; } } } return ans; } friend Mat operator ^ (Mat a, ull n){ Mat ans; ans.initunit (); while (n){ if (n&1) ans = ans*a; a = a*a; n >>= 1; } return ans; } }a, b; void init (){ sz = 1; clr (chd[0], 0); val[0] = 0; a.initzero (); b.a[0][0] = 26; b.a[0][1] = 1; b.a[1][0] = 0; b.a[1][1] = 1; } void insert (char* s){ int len = strlen (s); int p = 0; FOR (i, 0, len-1){ int c = code[s[i]]; if (!chd[p][c]){ val[sz] = 0; clr (chd[sz], 0); chd[p][c] = sz ++; } p = chd[p][c]; } val[p] = 1; } void getfail (){ queue<int> q; FOR (i, 0, CHD-1){ fail[chd[0][i]] = 0; if (chd[0][i]){ q.push (chd[0][i]); } } while (SIZE (q)){ int u = q.front (); q.pop (); FOR (i, 0, CHD-1){ if (chd[u][i]){ q.push (chd[u][i]); int t = fail[u]; fail[chd[u][i]] = chd[t][i]; val[chd[u][i]] += val[chd[t][i]]; }else{ chd[u][i] = chd[fail[u]][i]; } } } } int main (){ FOR (i, 'a', 'z'){ code[i] = i-'a'; } int n, m; while (~scanf ("%d%d", &n, &m)){ init (); char s[10]; FOR (i, 1, n){ RS (s); insert (s); } getfail (); FOR (i, 0, sz-1){ if (val[i] == 0){ FOR (j, 0, CHD-1){ if (val[chd[i][j]] == 0){ a.a[chd[i][j]][i] ++; } } } } FOR (i, 0, sz){ a.a[sz][i] = 1; } len = sz+1; a = a^m; len = 2; b = b^((ull)m+1ULL); ull ans = b.a[0][1]; FOR (i, 0, sz){ ans -= a.a[i][0]; } cout << ans << endl; } }

좋은 웹페이지 즐겨찾기