您的位置:首页 > 其它

BZOJ1009 [HNOI2008]GT考试

2014-09-28 18:52 225 查看
这是从我百度空间搬运来的,地址:http://hi.baidu.com/nstbzmzklnbaqrq/item/2c452a1ee8ce220ab98a1a11

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

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

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

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

/**************************************************************
Problem: 1009
User: rausen
Language: Pascal
Result: Accepted
Time:36 ms
Memory:424 kb
****************************************************************/

type
arr = array[0..30, 0..30] of longint;

var
an, i, j, k, n, m, prime : longint;
f, ans : arr;
p : array[0..50] of arr;
a : array[0..100] of longint;
ch : char;

function check(i, j, k : longint) : boolean;
var
i1, t : longint;

begin
if k = 0 then exit(true);
if j <> a[k] then
exit(false);
dec(k);
while k > 0 do begin
if a[k] = a[i] then begin
dec(k);
dec(i);
end else
exit(false);
end;
exit(true);
end;

operator * (const x, y : arr) z : arr;
var
i, j, k : longint;

begin
fillchar(z, sizeof(z), 0);
for i := 0 to m do
for j := 0 to m do
for k := 0 to m do
z[i, j] := z[i, j] + x[i, k] * y[k, j];
for i := 0 to m do
for j := 0 to m do
z[i, j] := z[i, j] mod prime;
end;

procedure power(n : longint);
var
i, j : longint;

begin
p[0] := f;
i := 0;
j := 1;
while j < n do begin
inc(i);
j := j shl 1;
p[i] := p[i - 1] * p[i - 1];
end;
fillchar(ans, sizeof(ans), 0);
for i := 0 to m do
ans[i, i] := 1;
i := 0;
while n > 0 do begin
if n and 1 = 1 then
ans := ans * p[i];
inc(i);
n := n shr 1;
end;
end;

begin
readln(n, m, prime);
for i := 1 to m do begin
read(ch);
a[i] := ord(ch) - ord('0');
end;
dec(m);
fillchar(f, sizeof(f), 0);
for i := 1 to m do
for j := 0 to 9 do
for k := i + 1 downto 0 do
if check(i, j, k) then begin
inc(f[i, k]);
break;
end;
f[0, 0] := 9;
f[0, 1] := 1;
fillchar(a, sizeof(a), 0);
a[0] := 1;
power(n);
an := 0;
for i := 0 to m do
an := an + ans[0, i];
writeln(an mod prime);
end.


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: