hdu 3306 矩阵构造

题意:

给一递推公式:

hdu 3306   矩阵构造 - wutyyzchangde - wutyyzchangde 的博客
求S(n)
hdu 3306   矩阵构造 - wutyyzchangde - wutyyzchangde 的博客
 其中:
hdu 3306   矩阵构造 - wutyyzchangde - wutyyzchangde 的博客
 思路:
因为A(n) = X*A(n-1)+Y*A(n-2),
所以,A(n) ^2= X^2*A(n-1)^2+Y^2*A(n-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*X*Y*A(n-1)*A(n-2)
构造矩阵如下:
| S(n)           |      | 1 X^2 Y^2 2XY |   | S(n-1)           |
| A(n)^2       | =   | 0 x^2 Y^2 2XY |    | A(n-1)^2       |
| A(n-1)^2    |      | 0 1     0     0     |    | A(n-2)^2       |
| A(n)A(n-1) |      | 0  X    0    Y     |    | A(n-1)A(n-2) |

 构造矩阵的过程注意递推式的使用。写代码 矩阵初始化时注意取模,防止溢出。

代码:

#include <stdio.h>
typedef struct
{
  int matrix[4][4];
}Matrix;

Matrix multi(Matrix x,Matrix y)
{
  Matrix res;
  int i,j,k;
  int sum;
  
  for(i = 0;i<4;i++)
    for(j = 0;j<4;j++)
    {
      sum = 0;
      for(k = 0;k<4;k++)
        sum+=(x.matrix[i][k]*y.matrix[k][j])%10007;
      res.matrix[i][j] = sum%10007;
    }
    return res;
}

Matrix powermod(Matrix x,int n)
{
  Matrix res;
  int i,j;
  
  for(i = 0;i<4;i++)
    for(j = 0;j<4;j++)
    {
       if(i==j)
        res.matrix[i][j] = 1;
       else
        res.matrix[i][j] = 0;
    }
    for(;n;n>>=1)
    {
      if(n&1)
        res = multi(res,x);
       x = multi(x,x);
    }
    return res;
}

int main()
{
  int N,X,Y;
  Matrix res;
  
  while(scanf("%d%d%d",&N,&X,&Y)!=EOF)
  {
      if(N==0||N==1)
      {
          printf("%d\n",N+1);
          continue;
      }
        X%=10007,Y%=10007;
        res.matrix[0][0] = 1;
        res.matrix[0][1] = (X*X)%10007;
        res.matrix[0][2] = (Y*Y)%10007;
        res.matrix[0][3] = (2*X*Y)%10007;
        res.matrix[1][0] = 0;
        res.matrix[1][1] = (X*X)%10007;
        res.matrix[1][2] = (Y*Y)%10007;
        res.matrix[1][3] = (2*X*Y)%10007;
        res.matrix[2][0] = 0;
        res.matrix[2][1] = 1;
        res.matrix[2][2] = 0;
        res.matrix[2][3] = 0;
        res.matrix[3][0] = 0;
        res.matrix[3][1] = X%10007;
        res.matrix[3][2] = 0;
        res.matrix[3][3] = Y%10007;
        res = powermod(res,N-1);
        printf("%d\n",(2*res.matrix[0][0]+res.matrix[0][1]+res.matrix[0][2]+res.matrix[0][3])%10007);
  }
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值