chenfy27的刷题记录

导航

leetcode2836 在传球游戏中最大化函数值

n名玩家在玩传球游戏,编号为i的玩家固定会把球传给编号为r[i]的玩家,任选一名玩家开始传球,恰好传k次,得分为这k次传球内所有接触过球的玩家的编号之和,如果玩家多次触球,则累加多次。问从哪个玩家开始传,能获得最大总得分,求最大得分。
1<=n<=1E5; 0<=r[i]<n; 1<=k<=1E10

分析:与倍增法求lca类似,记f[i][j]表示从玩家i开始传2^j次后到达的玩家编号,w[i][j]表示对应的得分(不含最后接球玩家)。

using i64 = long long;
class Solution {
public:
    long long getMaxFunctionValue(vector<int>& r, long long k) {
        int n = r.size();
        std::vector<std::vector<int>> f(n, std::vector<int>(35, 0));
        std::vector<std::vector<i64>> w(n, std::vector<i64>(35, 0));
        for (int i = 0; i < n; i++) {
            f[i][0] = r[i];
            w[i][0] = i;
        }
        for (int j = 1; j < 35; j++) {
            for (int i = 0; i < n; i++) {
                f[i][j] = f[f[i][j - 1]][j - 1];
                w[i][j] = w[i][j - 1] + w[f[i][j - 1]][j - 1];
            }
        }
        i64 ans = 0;
        for (int i = 0; i < n; i++) {
            i64 cur = 0;
            int x = i;
            for (int t = 34; t >= 0; t--) {
                if ((1LL << t) & k) {
                    cur += w[x][t];
                    x = f[x][t];
                }
            }
            ans = std::max(ans, cur + x);
        }
        return ans;
    }
};

posted on 2024-12-05 20:31  chenfy27  阅读(1)  评论(0编辑  收藏  举报