nyoj 301 递推求值

http://acm.nyist.net/JudgeOnline/problem.php?pid=301

递推求值

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

给你一个递推公式:

f(x)=a*f(x-2)+b*f(x-1)+c

并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。

注意:-1对3取模后等于2

输入
第一行是一个整数T,表示测试数据的组数(T<=10000)
随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)
输出
输出f(n)对1000007取模后的值
样例输入
2
1 1 1 1 0 5
1 1 -1 -10 -100 3
样例输出
5
999896


典型的矩阵乘法,这是一个3*3的矩阵乘法。

要注意的是 得出来的正确结果必须得(a%10000007)%10000007 这样才能得出正确的答案;

在矩阵相乘的过程中一定要注意  只能mod10000007 不能采用上述mod的方式。



 
#include<stdio.h>
struct node{
            long long a11,a12,a13,a21,a22,a23,a31,a32,a33;
           }ju,ju1;
struct nodebase{  
            long long x,y,z;
           }base;
           
nodebase matrix(node q,nodebase p)
            {
               nodebase ans;
               ans.x=q.a11*p.x + q.a12*p.y + q.a13*p.z       ;
            //   ans.y=q.a21*p.x + q.a22*p.y + q.a23*p.z       ;
            //   ans.z=q.a31*p.x + q.a32*p.y + q.a33*p.z       ; 
               ans.x=(ans.x%1000007+1000007)%1000007;
            //   ans.y=(ans.y%1000007+1000007);               
            //   ans.z=(ans.z%1000007+1000007);               
               
               return ans;        
            }          
node mat(node q,node p)
{
  node ans;
  ans.a11=q.a11*+p.a11+q.a12*p.a21+q.a13*q.a31;     
  ans.a12=q.a11*+p.a12+q.a12*p.a22+q.a13*q.a32;  
  ans.a13=q.a11*+p.a13+q.a12*p.a23+q.a13*q.a33;
    
  ans.a21=q.a21*+p.a11+q.a22*p.a21+q.a23*q.a31;  
  ans.a22=q.a21*+p.a12+q.a22*p.a22+q.a23*q.a32;   
  ans.a23=q.a21*+p.a13+q.a22*p.a23+q.a23*q.a33;
        
  ans.a31=q.a31*+p.a11+q.a32*p.a21+q.a33*q.a31;  
  ans.a32=q.a31*+p.a12+q.a32*p.a22+q.a33*q.a32;  
  ans.a33=q.a31*+p.a13+q.a32*p.a23+q.a33*q.a33;  
  
  ans.a11=ans.a11%1000007;    //这里应该注意 全部加上后再mod
  ans.a12=ans.a12%1000007;  
  ans.a13=ans.a13%1000007;
  ans.a21=ans.a21%1000007;    
  ans.a22=ans.a22%1000007;
  ans.a23=ans.a23%1000007;  
  ans.a31=ans.a31%1000007;
  ans.a32=ans.a32%1000007;
  ans.a33=ans.a33%1000007;

  return ans;
}       

node fun(int n)
          {
                if(n==1)return ju1;
                ju=fun(n/2);
                ju=mat(ju,ju);
                if(n%2==1)
                ju=mat(ju,ju1);
                return ju;
              
          }
int main()
{

     int x,n;
     nodebase c;
     scanf("%d",&x);
     while(x--)    
     {
         base.z=1;
         ju.a11=ju.a13=ju.a31=ju.a32=0;
         ju.a12=ju.a33=1;
         scanf("%lld %lld %lld %lld %lld %d",&base.x, &base.y, &ju.a21, &ju.a22, &ju.a23, &n);       
         ju1=ju;
        
         
         if(n==1){printf("%lld\n",base.x);continue;}
         ju=fun(n-1); 

         
         c=matrix(ju,base);
         printf("%lld\n",c.x);
     }
}



        




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值