Description

B 君有两个好朋友, 他们叫宁宁和冉冉. 有一天, 冉冉遇到了一个有趣的题目: 输入 \(b, d, n\), 求:

\[\left \lfloor (\frac{b + \sqrt{d}}{2})^n \right \rfloor \bmod 7528443412579576937\]

Input

一行三个整数 \(b, d, n\);

Output

一行一个数表示模 \(7528443412579576937\) 之后的结果.

Sample Input

1 5 9

Sample Output

76

Data Range

对于所有的数据, 满足:\(0 \lt b^2 \leq d \lt (b+1)^2 \leq 10^{18}, n \leq 10^{18}\);

同时所有数据满足:\(b \bmod 2 = 1, d \bmod 4 = 1\)

Explanation

应该是一道构造数列的题目, 构造完毕以后用矩阵快速幂优化即可~

顺便吐槽一下不开 unsigned long long 见祖宗这件事还是头一次遇到......

神犇题解 (传送门:http://blog.csdn.net/popoqqq/article/details/45148309)

构造数列 \(a_n = b \cdot a_{n-1} + \frac{d-b^2}{4} \cdot a_{n-2}\);

其中 \(a_0 = 2, a_1 = b\)

然后我们求出这个数列的通项公式, 得到 \((\frac{b+\sqrt{d}}{2})^n = a_n - (\frac{b-\sqrt{d}}{2})^n\)

由于 \(b \bmod 2 = 1, d \bmod 4 = 1\), 因此 \(\frac{d-b^2}{4}\) 一定是个正整数, 故我们可以利用矩阵乘法来求出这个数列的第 \(n\)

然后对于 80% 的数据 \(b_2 \leq d \lt (b+1)^2\), 对于 20% 的数据 \(b = 1, d = 5\), 因此 \(\frac{b-\sqrt{d}}{2} \in (-1, 0]\)

进一步可以用矩阵乘法瞎搞即可.

Source Code


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>

using namespace std;
typedef unsigned long long lli;
const lli modr = 7528443412579576937ull;

lli fast_mul(lli a, lli b)
{
    lli res = 0;
    for (a %= modr; b > 0; b >>= 1, a = (a + a) % modr)
        if (b & 1) res = (res + a) % modr;
    return res;
}

class matrix
{
public:
    lli dat[2][2];
    matrix(void)
    {
        dat[0][0] = dat[0][1] = 0ll;
        dat[1][0] = dat[1][1] = 0ll;
        return ;
    }
    matrix(lli v)
    {
        dat[0][0] = dat[1][1] = v;
        dat[0][1] = dat[1][0] = 0ll;
        return ;
    }
    matrix(lli a, lli b, lli c, lli d)
    {
        dat[0][0] = a; dat[0][1] = b;
        dat[1][0] = c; dat[1][1] = d;
        return ;
    }
};

matrix operator * (matrix a, matrix b)
{
    matrix c;
    c.dat[0][0] = (fast_mul(a.dat[0][0], b.dat[0][0]) + fast_mul(a.dat[0][1], b.dat[1][0])) % modr;
    c.dat[0][1] = (fast_mul(a.dat[0][0], b.dat[0][1]) + fast_mul(a.dat[0][1], b.dat[1][1])) % modr;
    c.dat[1][0] = (fast_mul(a.dat[1][0], b.dat[0][0]) + fast_mul(a.dat[1][1], b.dat[1][0])) % modr;
    c.dat[1][1] = (fast_mul(a.dat[1][0], b.dat[0][1]) + fast_mul(a.dat[1][1], b.dat[1][1])) % modr;
    return c;
}

matrix operator ^ (matrix a, lli b)
{
    matrix res = 1;
    for (; b > 0; b >>= 1, a = a * a)
        if (b & 1) res = res * a;
    return res;
}

lli b, d, n;

int main(int argc, char** argv)
{
    scanf("%lld%lld%lld", &b, &d, &n);
    lli A = b, B = (d - b * b) / 4;
    matrix wrk(0, 1, B, A);
    matrix mat(2, 0, b, 0);
    lli F = 0;
    if (b * b != d && n % 2 == 0)
        F = 1;
    lli res = ((wrk ^ n) * mat).dat[0][0] - F;
    res = res + modr % modr;
    printf("%lld\n", res);
    return 0;
}