题解 P7108 【移花接木】

数学题,高度 \(\infty\) 是为了防止你想多考虑嫁接是否够用。


分析:

  • \(\text{case1}\):当 \(a\ge b\) 时,只需要砍树就行,嫁接没有任何用处。

\(0\) 层要砍掉 \((a-b)\to(a-b)\times b^0\) 个树枝;

\(1\) 层要砍掉 \((a-b)\times b^1\) 个树枝;

\(2\) 层要砍掉 \((a-b)\times b^2\) 个树枝;

\(\cdots\)

\(h-1\) 层要砍掉 \((a-b)\times b^{h-1}\) 个树枝;

\(h\) 层要全部砍光,也就是 \(a\times b^h\) 个树枝。

所以一共砍掉了:

\[(a-b)\times\left(b^0+b^1+b^2+\cdots+b^{h-1}\right)+a\times b^h \]

\[=(a-b)\times \frac{1-b^h}{1-b}+a\times b^h \]

用快速幂 \(+\) 逆元直接求就行。

注意 \(b=1\) 时的特判。

  • \(\text{case2}\):当 \(a<b\) 时,先用嫁接把 \(h\) 层以下的枝补全了,再考虑把 \(h\) 层砍光。

换的时候可以贪心,用第 \(h\) 层的树枝嫁接给之前的。

\(0\) 层要接 \((b-a)\to (b-a)\times b^0\) 个树枝;

\(1\) 层由于上一层新添了 \(b-a\) 个树枝,所以要接 \((b-a)\times b^1\) 个树枝;

\(\cdots\)

\(h-1\) 层就要接 \((b-a)\times b^{h-1}\) 个树枝。

所以一共只需要 \(a\times b^h\) 次操作。

快速幂直接算。

时间复杂度是 \(\mathcal O(T\times log(h))\)


代码:

#include "cstdio"
#include "cctype"
#include "algorithm"
#define mod 1000000007
#define ll long long
ll ans, t, a, b, h;
char buffer[1 << 28], *S = buffer, puffer[1 << 28], *T = puffer;
inline ll read() {
    int x(0), f(0);

    while (!isdigit(*S))
        f |= (*S++ == '-');

    while (isdigit(*S))
        x = (x << 1) + (x << 3) + (*S++ ^ 48);

    return f ? -x : x;
}
inline void write(ll x) {
    int num[28], sp = 0;

    if (x < 0)
        *T++ = '-', x = -x;

    if (!x)
        *T++ = 48;

    while (x)
        num[++sp] = x % 10, x /= 10;

    while (sp)
        *T++ = num[sp--] + 48;
}
inline ll power(ll x, ll y) {
    ll res = 1;

    while (y) {
        if (y & 1)
            res = res * x % mod;

        x = x * x % mod;
        y >>= 1;
    }

    return res;
}
inline ll pomod(ll x) {
    return power(x, mod - 2);
}
int main() {
    fread(buffer, 1, 1 << 28, stdin);
    t = read();

    while (t--) {
        a = read(), b = read(), h = read();
        int k = power(b, h);

        if (a > b) {
            if (b == 1)
                write(((a - b)*h % mod + a * k % mod) % mod);
            else
                write(((a - b) * (k - 1) % mod * pomod(b - 1) % mod + a * k % mod) % mod);
        } else
            write(a * k % mod);

        *T++ = '\n';
    }

    fwrite(puffer, 1, T - puffer, stdout);
    return 0;
}
posted @ 2020-12-02 09:41  Nakiri_Ayame_suki  阅读(281)  评论(0编辑  收藏  举报