BZOJ1009 [HNOI2008]GT考试

这是从我百度空间搬运来的,地址:http://hi.baidu.com/nstbzmzklnbaqrq/item/2c452a1ee8ce220ab98a1a11

首先需要KMP进行匹配,但是发现模式串长度只有20,于是乱搞匹配(结果用的时间比KMP还多...)。

之后是DP:f[i, j]表示到了第i位时,后缀为模式串长度为j的前缀的字符串个数。(语文老师死得早><)

然后第一维明显可以用滚动数组压缩。

又第二维可以构造矩阵,用矩阵快速幂优化,于是搞定。

  1 /**************************************************************
  2     Problem: 1009
  3     User: rausen
  4     Language: Pascal
  5     Result: Accepted
  6     Time:36 ms
  7     Memory:424 kb
  8 ****************************************************************/
  9  
 10 type
 11   arr = array[0..30, 0..30] of longint;
 12  
 13 var
 14   an, i, j, k, n, m, prime : longint;
 15   f, ans : arr;
 16   p : array[0..50] of arr;
 17   a : array[0..100] of longint;
 18   ch : char;
 19  
 20 function check(i, j, k : longint) : boolean;
 21 var
 22   i1, t : longint;
 23  
 24 begin
 25   if k = 0 then exit(true);
 26   if j <> a[k] then
 27     exit(false);
 28   dec(k);
 29   while k > 0 do begin
 30     if a[k] = a[i] then begin
 31       dec(k);
 32       dec(i);
 33     end else
 34       exit(false);
 35   end;
 36   exit(true);
 37 end;
 38  
 39 operator * (const x, y : arr) z : arr;
 40 var
 41   i, j, k : longint;
 42  
 43 begin
 44   fillchar(z, sizeof(z), 0);
 45   for i := 0 to m do
 46     for j := 0 to m do
 47       for k := 0 to m do
 48         z[i, j] := z[i, j] + x[i, k] * y[k, j];
 49   for i := 0 to m do
 50     for j := 0 to m do
 51       z[i, j] := z[i, j] mod prime;
 52 end;
 53  
 54 procedure power(n : longint);
 55 var
 56   i, j : longint;
 57  
 58 begin
 59   p[0] := f;
 60   i := 0;
 61   j := 1;
 62   while j < n do begin
 63     inc(i);
 64     j := j shl 1;
 65     p[i] := p[i - 1] * p[i - 1];
 66   end;
 67   fillchar(ans, sizeof(ans), 0);
 68   for i := 0 to m do
 69     ans[i, i] := 1;
 70   i := 0;
 71   while n > 0 do begin
 72     if n and 1 = 1 then
 73       ans := ans * p[i];
 74     inc(i);
 75     n := n shr 1;
 76   end;
 77 end;
 78  
 79 begin
 80   readln(n, m, prime);
 81   for i := 1 to m do begin
 82     read(ch);
 83     a[i] := ord(ch) - ord('0');
 84   end;
 85   dec(m);
 86   fillchar(f, sizeof(f), 0);
 87   for i := 1 to m do
 88     for j := 0 to 9 do
 89       for k := i + 1 downto 0 do
 90         if check(i, j, k) then begin
 91           inc(f[i, k]);
 92           break;
 93         end;
 94   f[0, 0] := 9;
 95   f[0, 1] := 1;
 96   fillchar(a, sizeof(a), 0);
 97   a[0] := 1;
 98   power(n);
 99   an := 0;
100   for i := 0 to m do
101     an := an + ans[0, i];
102   writeln(an mod prime);
103 end.
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/3998826.html