首页 > 其他分享 >CF1879F Last Man Standing记录

CF1879F Last Man Standing记录

时间:2023-12-17 20:00:16浏览次数:31  
标签:Standing CF1879F le Last int res second vector first

CF1879F Last Man Standing

题目链接:https://codeforces.com/problemset/problem/1879/F

题意简述

有 $n$ 位英雄,每位英雄都有护甲值 $a$ 和生命值 $h$。对一次伤害值为 $x$ 的游戏,每位英雄的存活时间为 $t = \lceil a / x \rceil \cdot h$。

游戏进行无数次,伤害值从 $1$ 到无穷。某一次游戏中,存活时间最长的英雄获得等同于其单独存活的时间的分数。求每位英雄在单次游戏中获得分数的最大值。

$n, x, a \le 2 \times 10^5$。

题解(官解)

首先,显然所有 $\ge \max a$ 的伤害值等价,因此只需考虑 $1 \le x \le \max a$。

对该范围内每个 $x$,需要求出最大的两个 $t$ 以及最大的一个的下标。我们将护甲值按照 $c = \lceil a /x\rceil$ 分类,对每个 $x$ 枚举这一类别。则对相同的 $c$,即 $x\cdot(c-1) + 1 \le a \le x \cdot c$,$t$ 的相对大小即 $h$ 的相对大小。

枚举 $c$,只要能够在 $O(1)$ 时间内找到 $h$ 最大和次大的两个元素,根据调和级数的性质,即可在 $O(a\log a)$ 时间内求出最终答案——这可以通过 ST 表实现。注意合并时需要考虑两个区间内最大元素为同一个元素的情况(因为 ST 表可能有重叠)。

代码实现(C++)

#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;

using P = pair<int, int>;
void solve() {
    int n;
    cin >> n;
    vector<int> h(n), a(n);
    for (int &x : h)
        cin >> x;
    for (int &x : a)
        cin >> x;
    int m = ranges::max(a);
    auto add = [&h](P a, P b) {
        P res{-1, -1};
        if (a.first == -1 || (b.first != -1 && h[a.first] < h[b.first]))
            res.first = b.first;
        else res.first = a.first;
        for (auto i : {a.first, a.second, b.first, b.second}) {
            if (i != -1 && i != res.first &&
                (res.second == -1 || h[i] > h[res.second])) {
                res.second = i;
            }
        }
        return res;
    };
    vector st(19, vector<P>());
    st[0] = vector<P>(m + 1, {-1, -1});
    for (int i = 0; i < n; i++) {
        st[0][a[i]] = add(st[0][a[i]], {i, -1});
    }
    for (int b = 1; (1 << b) <= m + 1; b++) {
        st[b] = vector<P>(m + 1 + 1 - (1 << b));
        for (int i = 0; i + (1 << b) <= m + 1; i++) {
            st[b][i] = add(st[b - 1][i], st[b - 1][i + (1 << (b - 1))]);
        }
    }
    auto query = [&](int l, int r) {
        r = min(r, m);
        int len = 32 - 1 - countl_zero((unsigned)(r - l + 1));
        return add(st[len][l], st[len][r + 1 - (1 << len)]);
    };
    vector<i64> ans(n, 0);
    for (i64 x = 1; x <= m; x++) {
        i64 mx = 0, smx = 0;
        int idx = -1;
        for (i64 c = 1; c * x <= m + x - 1; c++) {
            auto [idx1, idx2] = query(x * (c - 1) + 1, x * c);
            for (int i : {idx1, idx2}) {
                if (i == -1) continue;
                auto t = c * h[i];
                if (t > mx) {
                    smx = mx;
                    mx = t, idx = i;
                } else if (t > smx) smx = t;
            }
        }
        if (~idx) ans[idx] = max(ans[idx], mx - smx);
    }
    for (i64 x : ans)
        cout << x << " ";
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
}

标签:Standing,CF1879F,le,Last,int,res,second,vector,first
From: https://www.cnblogs.com/cpchenpi/p/17909670.html

相关文章

  • ElasticSearch之Index modules
    索引的参数,分为两类:静态参数,仅支持在创建索引时指定,或者关闭索引后指定。动态参数,允许在索引工作期间指定或者修改。静态参数index.number_of_shards默认值为1。本参数用于控制主分片的数量,仅支持在创建时指定,对于已关闭的索引,修改本参数不会生效。es.index.max_number_o......
  • elasticsearch get查询方式
    api:(elasticsearch版本7.3)#通过id查询GET<index>/_doc/<_id>#判断是否存在HEAD<index>/_doc/<_id>#通过id查询GET<index>/_source/<_id>#判断是否存在HEAD<index>/_source/<_id>#查询指定index的多个文档GET/<index>/_mget#查询多个文......
  • elasticsearch 文档更新操作:update和update_by_query
    API:(elasticsearch版本7.3)POST/<index>/_update/<_id>POST/<index>/_update_by_query1.POST/<index>/_update/<_id>支持脚本,可以更新、删除或跳过修改文档。更新文档部分内容,传递部分文档,将其合并到现有文档中。#测试--post/update脚本修改文档POST/king_test_p......
  • elasticsearch 文档删除操作:delete和delete_by_query
    api:(elasticsearch版本7.3)#删除指定id的文档DELETE/<index>/_doc/<_id>#按查询条件删除POST/<index>/_delete_by_query1.DELETE/<index>/_doc/<_id>删除指定id的文档#测试--删除文档DELETE/king_test_person/_doc/223/2.POST/<index>/_dele......
  • 无涯教程-Java - int lastIndexOf(String str)函数
    如果string参数作为该对象中的子字符串出现一次或多次,则它返回最后出现的第一个字符的索引,如果没找到,则返回-1。intlastIndexOf-语法这是此方法的语法-publicintlastIndexOf(Stringstr)这是参数的详细信息-str   -  一个字符串。intlastIndexOf-返回值......
  • elasticsearch---修改文档
    修改有两种方式:全量修改:直接覆盖原来的文档增量修改:修改文档中的部分字段 全量修改是覆盖原来的文档,其本质是:根据指定的id删除文档新增一个相同id的文档注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。 增量修改增量修改......
  • 无涯教程-Java - int lastIndexOf(String str, int fromIndex)函数
    此方法返回最后一次出现的指定子字符串在此字符串内的索引,从指定索引(fromIndex)开始向后搜索。intlastIndexOf-语法publicintlastIndexOf(Stringstr,intfromIndex)这是参数的详细信息-fromIndex - 从中开始搜索的索引。str        - 一个......
  • 无涯教程-Java - int lastIndexOf(int ch, int fromIndex)函数
    此方法返回此对象表示的字符序列中该字符最后一次出现的索引,该索引小于或等于fromIndex,如果没找到,则返回-1。intlastIndexOf-语法publicintlastIndexOf(intch,intfromIndex)这是参数的详细信息-ch         - 一个字符。fromIndex  - 从......
  • 无涯教程-Java - int lastIndexOf(int ch)函数
    此方法返回此对象表示的字符序列中该字符最后一次出现的索引,如果没找到,则返回-1。intlastIndexOf-语法这是此方法的语法-intlastIndexOf(intch)这是参数的详细信息-ch   - 一个字符。intlastIndexOf-返回值此方法返回索引位置。intlastIndexOf-示例im......
  • ElasticSearch安装
    目录ES的安装与启动Linux系统环境准备修改虚拟内存空间大小修改最大文件描述符数量及最大线程数创建用户与密码ES的安装与配置ES的安装与启动Linux系统环境准备修改虚拟内存空间大小查询系统默认虚拟内存大小sysctl-a|grepvm.max_map_count发现系统提供的虚拟内存为64......