acm-递推求值

本文深入探讨了在ACM(算法竞赛)中如何利用递推公式进行数值计算,详细解析递推关系的建立与求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递推求值

时间限制: 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
来源
经典题目
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#define max 1000007
typedef struct numb
{
  long long a[3][3];
 
}numb;
numb arry;
numb test;
void mult(numb &x,numb y,numb z)
{
  memset(x.a,0,sizeof(x.a));
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
    {
      x.a[i][j]=0;
      for(int s=0;s<3;s++)
      {
        x.a[i][j]+=y.a[i][s]*z.a[s][j];
       
      x.a[i][j]%=max;
    }
}
int main()
{
  int t;
  scanf("%d",&t);
  while(t--)
  {
    int f1,f2,a,b,c,n;
    scanf("%d%d%d%d%d%d",&f1,&f2,&a,&b,&c,&n);
    if(n==1)
    {
      printf("%d\n",f1); 
    }
    else if(n==2)
    {
      printf("%d\n",f2);
    }
    else
    {
      memset(arry.a,0,sizeof(arry.a));//原矩阵
      arry.a[0][0]=f1;
      arry.a[0][1]=f2;
      arry.a[0][2]=c;
     
      memset(test.a,0,sizeof(test.a));//中间矩阵
      test.a[0][1]=a;
      test.a[1][0]=1;
      test.a[1][1]=b;
      test.a[2][1]=1;
      test.a[2][2]=1;
      n-=2;
      numb tmp;
      memset(tmp.a,0,sizeof(tmp.a));
 
      for(int i=0;i<3;i++)
        tmp.a[i][i]=1;
      while(n)
      {
        if(n&1)
          mult(tmp,tmp,test);
        n>>=1;
        mult(test,test,test); 
      }
      mult(arry,arry,tmp);
      if(arry.a[0][1]>0)
        printf("%d\n",arry.a[0][1]);
      else printf("%d\n",arry.a[0][1]+max);
   
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值