ADV-218 递推求值

来源:互联网 发布:linux file命令 源码 编辑:程序博客网 时间:2024/04/26 17:20

ADV-218 递推求值

问题描述

 已知递推公式:

  F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5,

  F(n, 2)=F(n-1, 1) + 3F(n-3, 1) + 2F(n-3, 2) + 3.

  初始值为:F(1, 1)=2, F(1, 2)=3, F(2, 1)=1, F(2, 2)=4,F(3, 1)=6, F(3,2)=5。   
输入n,输出F(n, 1)和F(n, 2),由于答案可能很大,你只需要输出答案除以99999999的余数。

输入格式

  输入第一行包含一个整数n。

输出格式

  输出两行,第一行为F(n, 1)除以99999999的余数,第二行为F(n, 2)除以99999999的余数。

样例输入

4

样例输出

14

21

数据规模和约定

  1<=n<=10^18

题目分析

写一个实现矩阵相乘的方法和实现矩阵快速幂的方法,用矩阵表示出递推关系式,注意初始值。

java实现

import java.util.Scanner;public class Main {    final static int mod = 99999999;    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        long n = sc.nextLong();        if (n == 1) {            System.out.println(2);            System.out.println(3);        }else if(n == 2){            System.out.println(1);            System.out.println(4);                  }else if(n == 3){            System.out.println(6);            System.out.println(5);                  }else{            long[][]a = {{0,1,0,0,2,0,5},                         {1,0,0,0,3,2,3},                         {1,0,0,0,0,0,0},                         {0,1,0,0,0,0,0},                         {0,0,1,0,0,0,0},                         {0,0,0,1,0,0,0},                         {0,0,0,0,0,0,1}};            long[][]b = {{6},{5},{1},{4},{2},{3},{1}};            long[][]x = Multiply_Matrix(Multiply_ksm(a, n-3), b);            long result1 = x[0][0]%mod;            long result2 = x[1][0]%mod;            System.out.println(result1);            System.out.println(result2);        }        sc.close();    }    public static long[][] Multiply_Matrix(long[][] a, long[][] b) {        long[][] c = new long[a.length][b[0].length];        for (int i = 0; i < a.length; i++) {            for (int j = 0; j < b[0].length; j++) {                long temp = 0;                for (int k = 0; k < b.length; k++) {                    temp = (temp + ((a[i][k] % mod) * (b[k][j] % mod)) % mod) % mod;                }                c[i][j] = temp;            }        }        return c;    }    public static long[][] Multiply_ksm(long[][] a, long k) {        long[][] d = new long[a.length][a[0].length];        if (k == 1) {            return a;        } else if (k == 2) {            return Multiply_Matrix(a, a);        } else if (k % 2 == 0) {            d = Multiply_ksm(Multiply_Matrix(a, a), k / 2);            return d;        } else {            d = Multiply_ksm(Multiply_Matrix(a, a), k / 2);            return Multiply_Matrix(d, a);        }    }}
0 0