• [均摊复杂度] Codeforces 1637E Best Pair


    题目大意

    给定一个长度为 \(n\) 的数组 \(a\)。给出如下定义:

    • 定义 \(cnt_x\)​ 为 \(x\) 在数组 \(a\) 中出现的次数
    • 定义 \(f(x,y)=(cnt_x+cnt_y)\cdot(x+y)\)

    同时,给定由 \(m\)无序数对 \((x_1,y_1),(x_2,y_2),\cdots,(x_m,y_m)\) 组成的集合 \(S\)

    你需要计算出 \(\max ⁡f(u,v)\),要求 \(u,v\) 都出现在数组中,\(u\neq v\),且 \((u,v)\) 不在集合 \(S\) 中。

    数据范围:

    • \(t\) 组数据,\(1\leq t\leq 10^4\)
    • \(2\leq n,\sum n\leq 3×10^5,0\leq m,\sum m\leq 3×10^5\)
    • \(1\leq a_i\leq 10^9\)

    题解

    学到了一个小trick,本题可以使用均摊复杂度的方法,使得看似暴力的方法通过。

    我们可以固定 \(x\),枚举 \(cnt_y\leq cnt_x\)\(cnt_y\)。对于一个 \(x\),枚举到的 \(cnt_y\) 至多有 \(cnt_x\) 个,因此这一步枚举复杂度为 \(O(\sum cnt_x)=O(n)\)

    当固定了 \(x\)\(cnt_y\) 时,我们去按降序枚举出现次数等于 \(cnt_y\) 的所有的 \(y\),若 \(x=y\)\((x,y)\) 被禁止,则跳过这个 \(y\),继续去枚举 \(y\),直到找到第一个合法的 \(y\),更新答案,并退出循环。遇到 \(x=y\)\((x,y)\) 被禁止的情况是 \(O(n+m)\)的。判断 \((x,y)\) 是否被禁止可以使用 set。不妨假设 \(n,m\) 同阶,于是时间复杂度为 \(O(n\log n)\)

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType& T) {
        elemType X = 0, w = 0; char ch = 0;
        while (!isdigit(ch)) { w |= ch == '-';ch = getchar(); }
        while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
        T = (w ? -X : X);
    }
    
    map<int, int> cnt;
    vector<int> vec[300010];
    set<pair<int, int>> s;
    int a[300010];
    int T, n, m;
    
    LL solve() {
        LL ans = 0;
        for (auto v : cnt) {
            int x = v.first;
            for (int i = 1;i <= v.second;++i) {
                for (auto y : vec[i]) {
                    if (x == y || s.count(make_pair(min(x, y), max(x, y)))) continue;
                    ans = max(ans, 1LL * (x + y) * (v.second + i));
                    break;
                }
            }
        }
        return ans;
    }
    
    int main() {
        Read(T);
        while (T--) {
            Read(n); Read(m);
            cnt.clear(); s.clear();
            for (int i = 1;i <= n;++i) { Read(a[i]); ++cnt[a[i]]; vec[i].clear(); }
            for (auto v : cnt)
                vec[v.second].push_back(v.first);
            for (int i = 1;i <= n;++i)
                if (!vec[i].empty()) sort(vec[i].begin(), vec[i].end(), greater<int>());
            for (int i = 1;i <= m;++i) {
                int x, y; Read(x); Read(y);
                s.insert(make_pair(min(x, y), max(x, y)));
            }
            printf("%I64d\n", solve());
        }
        return 0;
    }
    
  • 相关阅读:
    控制台内容保存为文件
    SpringBoot
    JAVA基础
    jenkins的.gradle目录结构说明和清理
    macos 签名+公证app生成dmg后,安装使用过程中崩溃
    MacOS命令行打包+签名+公证+生成dmg文件
    jenkins构建调用tar报错:tar: Failed to set default locale
    jenkins构建报错:appdmg: command not found
    jenkins 构建xcode-select -s 切换xcode版本失败 (切换xcode路径无效)
    jenkins 执行shell编译go 代码报错:build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined
  • 原文地址:https://www.cnblogs.com/AEMShana/p/15939410.html
Copyright © 2020-2023  润新知