• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mengxm
博客园    首页    新随笔    联系   管理    订阅  订阅

hdu 3306

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

矩阵连乘求解。

首先我们列一个式子 A(n)=x*A(n-1)+b*A(n-2);

则A(n)^2=x^2*A(n-1)^2+y^2*A(n-2)^2+2*x*y*A(n-1)*A(n-2);

也就是说S(n)=S(n-1)+A(n)^2=S(n-1)+x^2*A(n-1)^2+y^2*A(n-2)^2+2*x*y*A(n-1)*A(n-2);

我们从中取出不能直接求解的部分构成一个矩阵M={S(n-1),A(n-1)^2,A(n-2)^2,A(n-1)*A(n-2)}

然后由此可以看出有一个辅助矩阵D={1          0         0     0

                                                x^2      x^2     1     x

                                                y^2      y^2     0     0

                                                2*x*y   2*x*y  0     y}

第一列是S(n)与S(n-1)的转化方程

第二列是A(n)^2与A(n-1)^2的转化方程

第三列是为了将A(n-2)变为A(n-1)

第四列:

         x*A(n-1)^2+y*A(n-1)*A(n-2)=(x*A(n-1)+y*A(n-2))*A(n-1)=A(n)*A(n-1)

由此的我们可以很方便的从S(n-1)求解出S(n),只需要一个辅助矩阵

然后为了提高效率,可以采用二进制的思想(二进制思想具体参见北大程序设计引导及在线实践的P169)

本题要对最终结果模10007,所以为了防止溢出,我们可以在乘法后立即模10007,不会改变数值(模定理具体参见白书180)

 1 #include <stdio.h>
2 #include <memory.h>
3 #define SIZE 4
4 #define modle 10007
5
6 void ini_2(int x,int y,int (*matrix)[SIZE]) //初始化辅助矩阵
7 {
8 matrix[0][0]=matrix[1][2]=1;
9 matrix[0][1]=matrix[0][2]=matrix[0][3]=0;
10 matrix[2][2]=matrix[3][2]=matrix[2][3]=0;
11 matrix[1][0]=matrix[1][1]=(x*x)%modle;
12 matrix[2][0]=matrix[2][1]=(y*y)%modle;
13 matrix[3][0]=matrix[3][1]=(((x*y)%modle)*2)%modle;
14 matrix[1][3]=x;
15 matrix[3][3]=y;
16 }
17
18 void ini_1(int x,int y,int (*matrix)[SIZE]) //初始化主矩阵
19 {
20 memset(matrix,0,sizeof(matrix));
21 matrix[0][0]=2;
22 matrix[0][1]=1;
23 matrix[0][2]=1;
24 matrix[0][3]=1;
25 }
26
27 void matrix_mutiply(int (*matrix_1)[SIZE],int (*matrix_2)[SIZE]) //矩阵乘法
28 {
29 int matrix_cpy_1[4][4],matrix_cpy_2[4][4];
30 for(int i=0;i<4;i++)
31 for(int j=0;j<4;j++)
32 {
33 matrix_cpy_1[i][j]=matrix_1[i][j];
34 matrix_cpy_2[i][j]=matrix_2[i][j];
35 matrix_1[i][j]=0;
36 }
37 for(int i=0;i<4;i++)
38 for(int j=0;j<4;j++)
39 for(int k=0;k<4;k++)
40 matrix_1[i][j]+=matrix_cpy_1[i][k]*matrix_cpy_2[k][j],matrix_1[i][j]%=modle;
41 }
42 int main()
43 {
44 int matrix_1[SIZE][SIZE],matrix_2[SIZE][SIZE];
45 int number,x,y;
46 while(scanf("%d %d %d",&number,&x,&y)==3)
47 {
48 x%=modle,y%=modle;
49 ini_1(x,y,matrix_1);
50 ini_2(x,y,matrix_2);
51 number-=1;
52 while(number) //运用二进制提高效率
53 {
54 if(number&1)
55 matrix_mutiply(matrix_1,matrix_2);
56 matrix_mutiply(matrix_2,matrix_2);
57 number>>=1;
58 }
59 printf("%d\n",matrix_1[0][0]);
60 }
61 return 0;
62 }

  

posted @ 2011-07-19 08:41  mengxm  阅读(403)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3