• 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

  • 相关阅读:
    夺冠概率蓝桥杯
    Memcache配置
    [置顶] 6个月:从小白到程序员,也许没你想的那么难
    Delphi Messagebox自动关闭
    最近读园内的几篇好的文章的摘录及感悟
    近期项目的两点教训
    win7网络连接优先顺序设置方法
    WebSerivce学习笔记
    Delphi 控制摄像头操作
    郁闷的一天
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_2604_Lyon.html
Copyright © 2020-2023  润新知