5451 HDU Best Solver

链接: Best Solver

题目分析:

这个题目的关键点是需知道“共轭”.

如 :(A√B + C√D)  和 (A√B - C√D) 是共轭的

这个有一个规律 (A√B + C√D)^n + (A√B - C√D)^n  是一个整数(这里大家可以写写试试看)。

由题目可知:

因为我们要求的是:(5+2√6)^(1+2x), 我们可以构造一对共轭数。 (5-2√6),

因为0<(5-2√6) < 1, 所以 0<(5-2√6)^n < 1

故: 我们的式子由上述共轭的性质可知 y = (5+2√6)^(1+2x) + (5-2√6)^(1+2x) - 1;(y是要向下取整)

然后我们的y其实是有一个递推关系的:

F(n) = 10*F(n-1) - F(n-2).

证明如下:

设: Sn = (5+2√6)^n + (5-2√6)^n;

Sn * ( (5+2√6) + (5-2√6) )  = Sn * 10 = Sn+1 + Sn-1 * 1;

故: Sn+1 = 10*Sn  - Sn-1;

=================================================================================================

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL INF = 0xfffffff;
const LL maxn = 50005;
int dp[maxn];
int GetLoop(int m)
{
    memset(dp, 0, sizeof(dp));
    dp[0] = 2%m;
    dp[1] = 10%m;
    for(int i=2; i<=maxn-5; i++)
    {
        dp[i] = (10*dp[i-1] - dp[i-2]+m)%m;

        if(dp[i] == dp[1] && dp[i-1] == dp[0])
            return i-1;
    }
    return -1;
}
int QuickPow(int a,int b,int MOD)
{
    int ans = 1, k = a;

    while(b)
    {
        if(b%2 == 1)
            ans = (ans * k)%MOD;
        k = (k * k)%MOD;
        b /= 2;
    }
    return (ans+1)%MOD;
}



int main()
{
    int T, n, m, cas = 1;
    cin >> T;
    while(T--)
    {
        cin >> n >> m;

        int LoopNode =  GetLoop(m);
        int ans = QuickPow(2, n, LoopNode);
        printf("Case #%d: %d\n",cas++, (dp[ans%LoopNode] - 1)%m);
    }
    return 0;
}

 

posted @ 2015-09-23 19:26  向前走丶不回首  阅读(117)  评论(0编辑  收藏  举报