• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

hdu 2604 Queuing (Matrix)

http://acm.hdu.edu.cn/showproblem.php?pid=2604

  题意是找出长度为n的,不包含“fmf”或“fff”的字符串的个数。

  这题我是直接套用之前的ac自动机的模板的,构造出自动机,然后利用矩阵快速幂求出结果。当然,这题可以直接推出递推公式,然后再套入矩阵中。复杂度O(m^2 log n),其中m是矩阵大小,n是要求计算的长度。

代码如下:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 
  6 using namespace std;
  7 
  8 const int MS = 20;
  9 int CS = MS;
 10 int MOD = 30;
 11 
 12 struct Mat {
 13     int val[MS][MS];
 14     Mat(int u = 0) {
 15         for (int i = 0; i < CS; i++) {
 16             for (int j = 0; j < CS; j++) {
 17                 val[i][j] = 0;
 18             }
 19             val[i][i] = u % MOD;
 20         }
 21     }
 22     void print() {
 23         puts("Debug:");
 24         for (int i = 0; i < CS; i++) {
 25             for (int j = 0; j < CS; j++) {
 26                 cout << val[i][j] << ' ';
 27             }
 28             cout << endl;
 29         }
 30         puts("~~~~~~");
 31     }
 32 } Base, op;
 33 
 34 Mat operator + (Mat &a, Mat &b) {
 35     Mat ret;
 36     for (int i = 0; i < CS; i++) {
 37         for (int j = 0; j < CS; j++) {
 38             ret.val[i][j] = (a.val[i][j] + b.val[i][j]) % MOD;
 39         }
 40     }
 41     return ret;
 42 }
 43 
 44 Mat operator * (Mat &a, Mat &b) {
 45     Mat ret = Mat();
 46     for (int i = 0; i < CS; i++) {
 47         for (int k = 0; k < CS; k++) {
 48             if (a.val[i][k]) {
 49                 for (int j = 0; j < CS; j++) {
 50                     ret.val[i][j] += a.val[i][k] * b.val[k][j];
 51                     ret.val[i][j] %= MOD;
 52                 }
 53             }
 54         }
 55     }
 56     return ret;
 57 }
 58 
 59 Mat operator ^ (Mat &a, int p) {
 60     Mat t = a;
 61     Mat ret = Mat(1);
 62     while (p > 0) {
 63         if (p & 1) ret = ret * t;
 64         t = t * t;
 65         p >>= 1;
 66     }
 67     return ret;
 68 }
 69 
 70 const int kind = 2;
 71 const int N = 10;
 72 int root, cntNode;
 73 
 74 struct Node {
 75     int c[kind];
 76     int fail;
 77     bool end;
 78     void init() {
 79         memset(c, -1, sizeof(c));
 80         fail = -1;
 81         end = false;
 82     }
 83 } node[N];
 84 int Q[N], qh, qt;
 85 
 86 void init() {
 87     root = cntNode = 0;
 88     node[root].init();
 89 }
 90 
 91 void insert(char *s) {
 92     int p = root, idx;
 93     while (*s) {
 94         idx = (*s == 'f');
 95         if (node[p].c[idx] == -1) {
 96             node[++cntNode].init();
 97             node[p].c[idx] = cntNode;
 98         }
 99         p = node[p].c[idx];
100         s++;
101     }
102     node[p].end = true;
103 }
104 
105 void buildMat() {
106     op = Mat();
107     Base = Mat();
108     Base.val[0][0] = 1;
109     qh = qt = 1;
110     Q[qt++] = root;
111     while (qh < qt) {
112         int u = Q[qh++];
113         for (int i = 0; i < kind; i++) {
114             int c = node[u].c[i];
115             if (~c) {
116                 if (u == root) {
117                     node[c].fail = root;
118                 } else {
119                     node[c].fail = node[node[u].fail].c[i];
120                     if (node[node[c].fail].end) node[c].end = true;
121                 }
122                 Q[qt++] = c;
123             } else {
124                 if (u == root) {
125                     node[u].c[i] = root;
126                 } else {
127                     node[u].c[i] = node[node[u].fail].c[i];
128                 }
129             }
130         }
131     }
132     for (int i = 0; i < CS; i++) {
133         if (node[i].end) continue;
134         for (int j = 0; j < kind; j++) {
135             int t = node[i].c[j];
136             if (node[t].end) continue;
137             op.val[i][t]++;
138         }
139     }
140 }
141 
142 void PRE() {
143     char *str[2] = { "fmf", "fff"};
144     init();
145     insert(str[0]);
146     insert(str[1]);
147     CS = cntNode + 1;
148     buildMat();
149 }
150 
151 int main() {
152     int n;
153     PRE();
154 //    op.print();
155     while (cin >> n >> MOD) {
156         Base = op;
157         Base = Base ^ n;
158 //        Base.print();
159         int ans = 0;
160         for (int i = 0; i < CS; i++) {
161             ans += Base.val[0][i];
162             ans %= MOD;
163         }
164         cout << ans << endl;
165     }
166     return 0;
167 }
View Code

 

——written by Lyon

posted @ 2013-05-26 19:52  LyonLys  阅读(152)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3