HDU 5451

题目要求:y = (5 + 2√6)1+2^x

设An=(5 + 2√6)n,Bn=(5 - 2√6)n

Cn = An + Bn

显然Cn是正整数,且Bn是小于1的

所以我们所求的答案其实就是Cn - 1

通过推导:

Cn * [(5 + 2√6) + (5 - 2√6)] = 

((5 + 2√6)n + (5 - 2√6)n) * [(5 + 2√6) + (5 - 2√6)] =

(5 + 2√6)n + 1 + (5 - 2√6)n + 1) + (5 + 2√6)n - 1 + (5 - 2√6)n - 1)

10 * Cn = Cn + 1 + Cn - 1

Cn + 1 = 10 * Cn - Cn-1

我们找出了递推式,然后我们发现指数特别的大,M是个素数

于是我们可以实力地打一个表

/***********************************
*                                  *
*    Auther Rhapsody               *
*    E-mail addf400@foxmail.com    *
*                                  *
***********************************/
#include <set>
#include <map>
#include <cmath>
#include <deque>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

#define MP make_pair
#define PB push_back

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 5e6 + 7;
const int INF = 0x3f3f3f3f;

int MOD = 1e9 + 7;

int f[N];

//map <PII, int> Mapper;

int pow_mod(int x, int y, int MOD) {
    int Ans = 1;
    while (y) {
        if (y & 1)
            Ans = (LL)Ans * x % MOD;
        x = (LL)x * x % MOD;
        y >>= 1;
    }
    return Ans;
}

int find(int a, int idx, int MOD) {
    int x = pow_mod(2, a, MOD);
    x = (x + 1 - idx) % MOD;
    x = (x + MOD) % MOD;
    return idx - MOD + x;
}

int main(void) {
    int T, Test = 0;
    scanf("%d", &T);
    int a, m;
    while (T--) {
        scanf("%d%d", &a, &m);
        MOD = m;
        //Mapper.clear();
        f[0] = 2 % MOD;
        f[1] = 10 % MOD;
        //Mapper[MP(f[1], f[0])] = 1;
        int idx = 2, loop, S;
        while (true) {
            f[idx] = (f[idx - 1] * 10 - f[idx - 2]) % MOD;
            f[idx] = (f[idx] + MOD) % MOD;
            //PII t = MP(f[idx], f[idx - 1]);
            if (f[idx] != f[1] || f[idx - 1] != f[0]) {
                //Mapper[t] = idx++;
                ++idx;
                continue;
            }
            S = idx;
            loop = idx - 1;
            break;
        }
        int sum = 1;
        bool flag = true;
        for (int i = 1; i <= a; ++i) {
            sum = sum * 2;
            if (sum + 1 > S) {
                flag = false;
                break;
            }
        }
        if (flag) {
            printf("Case #%d: %d
", ++Test, (f[sum + 1] - 1 + MOD) % MOD);
            continue;
        }
        printf("Case #%d: %d
", ++Test, (f[find(a, S, loop)] - 1 + MOD) % MOD);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/addf/p/4834108.html