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;
}

 

posted @ 2012-09-16 21:27  qingyezhu  阅读(810)  评论(0编辑  收藏  举报