2326: [HNOI2011]数学作业 - BZOJ

首先是DP,分段DP(按位数讨论)

然后每一段构造出它对应的矩阵,用矩阵快速幂加速

 1 type
 2         matrix=array[1..3,1..3]of int64;
 3 var
 4         n,m:int64;
 5         a,b,c,d:matrix;
 6  
 7 function min(x,y:int64):int64;
 8 begin
 9         if x<y then exit(x);
10         exit(y);
11 end;
12  
13 procedure cheng(var a,b:matrix);
14 var
15         i,j,k:longint;
16 begin
17         for i:=1 to 3 do
18           for j:=1 to 3 do
19             d[i,j]:=0;
20         for i:=1 to 3 do
21           for j:=1 to 3 do
22             for k:=1 to 3 do
23               d[i,j]:=(d[i,j]+a[i,k]*b[k,j])mod m;
24         a:=d;
25 end;
26  
27 procedure main;
28 var
29         k,s:int64;
30         i:longint;
31 begin
32         read(n,m);
33         for i:=1 to 3 do
34           a[i,i]:=1;
35         b[2,1]:=1;
36         b[2,2]:=1;
37         b[3,2]:=1;
38         b[3,3]:=1;
39         k:=1;
40         while n>=k do
41           begin
42             b[1,1]:=(k*10)mod m;
43             c:=b;
44             s:=min(n,k*10-1)-k+1;
45             while s>0 do
46               begin
47                 if s and 1=1 then cheng(a,c);
48                 cheng(c,c);
49                 s:=s>>1;
50               end;
51             k:=k*10;
52           end;
53         write((a[2,1]+a[3,1])mod m);
54 end;
55  
56 begin
57         main;
58 end.
View Code

 

posted @ 2014-04-16 09:46  Randolph87  阅读(287)  评论(0编辑  收藏  举报