【题解】Codeforces Round 962 (Div. 3) F-Bomb

原题链接

题意

给你一个数组 a 和数组 b, 每次操作可以任选一个 a i a_i ai, 获得收益为 a i a_i ai 的大小, 但此后的要执行 a i − = b i a_i-=b_i ai=bi. 问执行 k 次后最大收益是多少. k 最大为 1 e 9 1e9 1e9.

思路

  • 第一想法就是优先队列模拟 k 次操作, 但发现 k 很大, 铁定 tle.
  • 注意到当某个 a [ i ] − x b [ i ] a[i]-xb[i] a[i]xb[i](x 为 a[i] 被选择的次数 ) 被选择时, 所有在优先队列做法中比它大的数一定都被选过了, 假如 v a l = a [ i ] − x b [ i ] val=a[i]-xb[i] val=a[i]xb[i] 是我最后一次操作选择的数. 那么我所有之前选择的数都不会小于 val.
  • 对于一个 a i a_i ai, 知道它会被选择的最小可能值, 就能算出来对他操作了多少次. max(0, (a[i] - val) / b[i] + (a[i] >= val ? 1 : 0)).
  • 我们就可以二分检查所有可能的 val, 去 check 它所对应的操作次数 times, 找到最小的 val 使 t i m e s < k times<k times<k, 可知 val 之上的所有都是被取的, 剩下的 k − t i m e s k-times ktimes 次, 显然都是取 val 的.

代码:

#define int long long

int solve(int _) {
    int n, k;
    cin >> n >> k;
    vector<int>a(n), b(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> b[i];
    }

    auto check = [&](int x) -> bool {
        int num = 0;
        for (int i = 0; i < n; ++i) {
            num += max(0ll, (a[i] - x) / b[i] + (a[i] >= x ? 1 : 0));
        }
        if (num >= k)return true;
        return false;
    };

    int l = 0, r = 1e18;
    while (l < r) {
        int mid = (r + l + 1) >> 1;
        if (check(mid)) {
            l = mid;
        }
        else {
            r = mid - 1;
        }
    }

    int p = r + 1, ans = 0;
    for (int i = 0; i < n; ++i) {
        int tim = max(0ll, (a[i] - p) / b[i] + (a[i] >= p ? 1 : 0));
        k -= tim;
        if (tim)ans += a[i] * tim - (tim - 1) * tim / 2 * b[i];
    }
    ans += k * r;
    return ans;
}
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值