zoukankan      html  css  js  c++  java
  • 题解 P7108 【移花接木】

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


    分析:

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

    (0) 层要砍掉 ((a-b) o(a-b) imes b^0) 个树枝;

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

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

    (cdots)

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

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

    所以一共砍掉了:

    [(a-b) imesleft(b^0+b^1+b^2+cdots+b^{h-1} ight)+a imes b^h ]

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

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

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

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

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

    (0) 层要接 ((b-a) o (b-a) imes b^0) 个树枝;

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

    (cdots)

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

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

    快速幂直接算。

    时间复杂度是 (mathcal O(T imes 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++ = '
    ';
        }
    
        fwrite(puffer, 1, T - puffer, stdout);
        return 0;
    }
    
  • 相关阅读:
    浅谈ASP.NET核心对象
    SQL MID() 函数
    如何查看linux系统CPU利用率 简单
    canvas 学习笔记 简单
    linux 为用户设定、修改密码 passwd 简单
    转crontab用法(例子) 简单
    mongodb加入系统服务 简单
    转导出csv文件时,处理分隔符问题 简单
    tar和gzip、unzip命令详解 简单
    linux创建用户命令 简单
  • 原文地址:https://www.cnblogs.com/nakiri-ayame-suki/p/14072035.html
Copyright © 2011-2022 走看看