『HDU 5950』Recursive sequence 沈阳赛

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950

题意:就是有个农夫,在黑板上写了2个数字a,b.所有的牛报数,第一只牛报a,第二只牛报b,第n只牛报sum=2*A(n-2)+A(n-1)+n^4。求点n只牛报的数.

解释:
看到给你一排数,然后重复做几次的数,想都不用想,矩阵快速幂…
这里写图片描述

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const ll mod=2147493647;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }
 int T;
 ll N,a,b;

 typedef vector<ll> vec;
 typedef vector<vec> mat;

 mat mul(mat &A,mat &B)
 {
    mat C(A.size(),vec(B[0].size()));
    for(int i=0;i<A.size();i++)
    {
        for(int k=0;k<B.size();k++)
        {
            for(int j=0;j<B[0].size();j++)
            {
                C[i][j]=(C[i][j]+A[i][k]*B[k][j])%mod;
            }
        }
    }
    return C;
 }

 mat pow(mat A,ll n)
 {
     mat B(A.size(),vec(A.size()));
     for(int i=0;i<A.size();i++)
     {
         B[i][i]=1;
     }
     while(n>0)
     {
         if(n&1) B=mul(B,A);
         A=mul(A,A);
         n>>=1;
     }
     return B;
 }
 ll n;
 void solve()
 {
     mat A(7,vec(7));

     A[0][0]=0;A[0][1]=1;A[0][2]=0;A[0][3]=0;A[0][4]=0;A[0][5]=0;A[0][6]=0;
     A[1][0]=2;A[1][1]=1;A[1][2]=1;A[1][3]=4;A[1][4]=6;A[1][5]=4;A[1][6]=1;
     A[2][0]=0;A[2][1]=0;A[2][2]=1;A[2][3]=4;A[2][4]=6;A[2][5]=4;A[2][6]=1;
     A[3][0]=0;A[3][1]=0;A[3][2]=0;A[3][3]=1;A[3][4]=3;A[3][5]=3;A[3][6]=1;
     A[4][0]=0;A[4][1]=0;A[4][2]=0;A[4][3]=0;A[4][4]=1;A[4][5]=2;A[4][6]=1;
     A[5][0]=0;A[5][1]=0;A[5][2]=0;A[5][3]=0;A[5][4]=0;A[5][5]=1;A[5][6]=1;
     A[6][0]=0;A[6][1]=0;A[6][2]=0;A[6][3]=0;A[6][4]=0;A[6][5]=0;A[6][6]=1;

     n=N-2;

     mat B(7,vec(1));

     B[0][0]=a%mod;
     B[1][0]=b%mod;
     B[2][0]=2*2*2*2;
     B[3][0]=2*2*2;
     B[4][0]=2*2;
     B[5][0]=2;
     B[6][0]=1;

     A=pow(A,n);

     A=mul(A,B);

     printf("%I64d\n",A[1][0]);

 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
     scanf("%d",&T);
     while(T--)
     {
         scanf("%I64d%I64d%I64d",&N,&a,&b);
         if(N==0){printf("0\n");continue;}
         if(N==1){printf("%I64d\n",a);continue;}
         if(N==2){printf("%I64d\n",b);continue;}
         solve();
     }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值