专栏文章

题解:P5870 [SEERC 2018] Modern Djinn

P5870题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq3z2qw
此快照首次捕获于
2025/12/03 22:34
3 个月前
此快照最后确认于
2025/12/03 22:34
3 个月前
查看原文
这道题还算难的。
原先我的时间复杂度为 O(T×M2)O(T \times M^2),要想不超时应降到 O(T×M)O(T \times M) 及以下。
方法是使用哈希表(unordered map)统计每个人 YY 被多少愿望指向,这样就可以在 O(M)O(M) 的时间内统计每个愿望的影响范围。
我们还要使用贪心,按照影响范围从大到小排序,选择前M/4+1 ⌊M/4⌋ + 1 个愿望。
即使这样也会超时,我们要在排序上动手脚,使用快速排序找到前 KK 个最大的影响范围,完全排序肯定超时。
时间复杂度 O(T×M)O(T \times M),对于:
T:104T:10^4
M:105×2M:10^5 \times 2
是完全可以过的。
代码重要部分:
CPP
  while (T--) {
        int N, M;
        cin >> N >> M;
        vector<pair<int, int>> wishs(M);
        for (int i = 0; i < M; ++i) {
            cin >> wishs[i].first >> wishs[i].second;
        }
        // 预处理每个人的愿望列表
        vector<vector<int>> wish(N + 1);
        for (int i = 0; i < M; ++i) {
            int X = wishs[i].first;
            wish[X].push_back(i);
        }

        // 统计每个愿望的影响范围
        vector<int> fanwei(M, 0);
        for (int i = 0; i < M; ++i) {
            int Y = wishs[i].second;
            fanwei[i] = wish[Y].size();
        }

        // 按照影响范围从大到小排序
        vector<int> paixv(M);
        for (int i = 0; i < M; ++i) {
            paixv[i] = i;
        }
        sort(paixv.begin(), paixv.end(), [&](int a, int b) {
            return fanwei[a] > fanwei[b];
        });
}

因为怕抄题解,所以给重要部分(其实也就省去了输入和输出)。
为了让大家理解,数组名特意改了。

评论

0 条评论,欢迎与作者交流。

正在加载评论...