hdu 4291 a short problem

利用矩阵法求f(n),其中f(n)=3*f(n-1)+f(n-2) f(0)=0,f(1)=1

接着就是求循环节,即可。

求循环节:

#include<iostream>

#include<stdio.h>

using namespace std;

typedef long long LL;

const LLMOD = 1000000007LL;

int main() {

    LL f0 = 0, f1 = 1, temp = -1;

    for (LL i = 1;; i++) {

        temp = (3 * f1 + f0) % MOD;

        f0 = f1;

        f1 = temp;

        if (f0 == 0 && f1 == 1) {

            printf("%I64d\n", i);

            break;

        }

    }

    return 0;

}



//const LL MOD = 1000000007LL;

//222222224



//const LL MOD = 222222224LL;

//183120

 

 

 

 

 

import java.io.BufferedInputStream;

import java.util.Scanner;



public class Main {

    public static void main(String[] args) {

        Scanner cin = new Scanner(new BufferedInputStream(System.in));

        long n = -1;

        while (cin.hasNext()) {

            n = cin.nextLong();

            System.out.println(cal(cal(cal(n, 183120), 222222224), 1000000007));

        }

        cin.close();

    }



    static long numa[][] = new long[2][2];

    static long numb[][] = new long[2][2];



    public static void matrix(long[][] a, long[][] b, int mark, long MOD) {

        long[][] temp = new long[2][2];

        temp[0][0] = (a[0][0] * b[0][0] % MOD + a[0][1] * b[1][0] % MOD) % MOD;

        temp[0][1] = (a[0][0] * b[0][1] % MOD + a[0][1] * b[1][1] % MOD) % MOD;

        temp[1][0] = (a[1][0] * b[0][0] % MOD + a[1][1] * b[1][0] % MOD) % MOD;

        temp[1][1] = (a[1][0] * b[0][1] % MOD + a[1][1] * b[1][1] % MOD) % MOD;

        if (mark == 1) {

            for (int i = 0; i < 2; i++) {

                for (int j = 0; j < 2; j++) {

                    numa[i][j] = temp[i][j];

                }

            }

        } else {

            for (int i = 0; i < 2; i++) {

                for (int j = 0; j < 2; j++) {

                    numb[i][j] = temp[i][j];

                }

            }

        }

    }



    public static long cal(long n, long MOD) {

        numa[0][0] = 1;

        numa[0][1] = 0;

        numa[1][0] = 0;

        numa[1][1] = 1;

        numb[0][0] = 3;

        numb[0][1] = 1;

        numb[1][0] = 1;

        numb[1][1] = 0;



        while (n != 0) {

            if (n % 2 == 1) {

                matrix(numa, numb, 1, MOD);

            }

            matrix(numb, numb, 0, MOD);

            n >>= 1;

        }

        return numa[0][1];

    }

}

 

 

/*

 * Main.cpp

 *

 *  Created on: 2012-9-16

 *      Author: wangzhu

 */

#include<iostream>

#include<stdio.h>

#include<math.h>

using namespace std;

#define LL long long

LL numa[2][2], numb[2][2];

void matrix(LL a[2][2], LL b[2][2], int mark, LL MOD) {

    LL temp[2][2];

    temp[0][0] = (a[0][0] * b[0][0] % MOD + a[0][1] * b[1][0] % MOD) % MOD;

    temp[0][1] = (a[0][0] * b[0][1] % MOD + a[0][1] * b[1][1] % MOD) % MOD;

    temp[1][0] = (a[1][0] * b[0][0] % MOD + a[1][1] * b[1][0] % MOD) % MOD;

    temp[1][1] = (a[1][0] * b[0][1] % MOD + a[1][1] * b[1][1] % MOD) % MOD;

    if (mark) {

        for (int i = 0; i < 2; i++) {

            for (int j = 0; j < 2; j++) {

                numa[i][j] = temp[i][j];

            }

        }

    } else {

        for (int i = 0; i < 2; i++) {

            for (int j = 0; j < 2; j++) {

                numb[i][j] = temp[i][j];

            }

        }

    }

}

LL cal(LL n, LL MOD) {

    numa[0][0] = 1;

    numa[0][1] = 0;

    numa[1][0] = 0;

    numa[1][1] = 1;

    numb[0][0] = 3;

    numb[0][1] = 1;

    numb[1][0] = 1;

    numb[1][1] = 0;



    while (n) {

        if (n & 1) {

            matrix(numa, numb, 1, MOD);

        }

        matrix(numb, numb, 0, MOD);

        n >>= 1;

    }

    return numa[0][1];

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("data.in", "r", stdin);

#endif

            LL n;

            while (~scanf("%I64d", &n)) {

                printf("%I64d\n",

                        cal(cal(cal(n, 183120LL), 222222224LL),1000000007LL));

        }

        return 0;

}

 

你可能感兴趣的:(HDU)