首页 > 其他分享 >he 2024 ICPC Asia East Continent Online Contest (I)

he 2024 ICPC Asia East Continent Online Contest (I)

时间:2024-09-17 21:24:22浏览次数:1  
标签:nl Contest int Asia ICPC cnt2 cnt1 nr nv

A. World Cup

这道题目难点主要是读懂题意,然后按照题意手玩一下就出来了。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;

void solve() {
    int n = 32;
    vi a(n);
    for (auto &i: a) cin >> i;
    int cnt = 0;
    for (int i = 1; i < n; i++)
        cnt += a[0] > a[i];
    if (cnt < 2) cout << "32\n";
    else if (cnt < 6) cout << "16\n";
    else if (cnt < 13) cout << "8\n";
    else if (cnt < 27) cout << "4\n";
    else if (cnt < 31) cout << "2\n";
    else cout << "1\n";
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

F. Make Max

可以想到的是,一定是吧最小值一点点变大,这样是最优的。

那么我们就应该假设我们找到了最小值,并且最小值是连续的一段\([l,r]\)我们就应该找到这一段的左侧和右侧,选取较小值吧这一段变大,产生的贡献就是\(r-1+1\)。

这里我用了类似珂朵莉树的方法,分别按照顺序维护段和大小维护段,然后暴力的模拟就好了,以为每次操作可以使得段的数量至少减1,复杂度\(O(N\log N)\)

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;

struct seg1 {
    int l, r, v;

    seg1(int l, int r = 0, int v = 0) : l(l), r(r), v(v) {}

    bool operator<(const seg1 &b) const {
        return l < b.l;
    }
};

struct seg2 {
    int l, r, v;

    seg2(int l, int r = 0, int v = 0) : l(l), r(r), v(v) {}

    bool operator<(const seg2 &b) const {
        if (v != b.v) return v < b.v;
        return l < b.l;
    }
};

void solve() {
    int n;
    cin >> n;
    set<seg1> cnt1;
    set<seg2> cnt2;
    vi a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int l = 1, r; l <= n;) {
        r = l;
        while (r + 1 <= n and a[r + 1] == a[l]) r++;
        cnt1.emplace(l, r, a[l]);
        cnt2.emplace(l, r, a[l]);
        l = r + 1;
    }
    int res = 0;
    while (cnt2.size() > 1) {
        auto [l, r, v] = *cnt2.begin();
        cnt2.erase(cnt2.begin());
        cnt1.erase(cnt1.lower_bound(seg1(l, r, v)));
        res += r - l + 1;
        auto it = cnt1.lower_bound(seg1(l));
        if (it == cnt1.end()) {
            it = prev(it);
            auto [nl, nr, nv] = *it;
            cnt1.erase(it);
            cnt2.erase(cnt2.lower_bound(seg2(nl, nr, nv)));
            nl = min(nl, l), nr = max(nr, r), nv = max(nv, v);
            cnt1.emplace(nl, nr, nv);
            cnt2.emplace(nl, nr, nv);
        } else if (it == cnt1.begin()) {
            auto [nl, nr, nv] = *it;
            cnt1.erase(it);
            cnt2.erase(cnt2.lower_bound(seg2(nl, nr, nv)));
            nl = min(nl, l), nr = max(nr, r), nv = max(nv, v);
            cnt1.emplace(nl, nr, nv);
            cnt2.emplace(nl, nr, nv);
        } else {
            auto pit = prev(it);
            if (pit->v == it->v) {
                auto [nl, nr, nv] = *it;
                cnt1.erase(it);
                cnt2.erase(cnt2.lower_bound(seg2(nl, nr, nv)));
                auto [pl, pr, pv] = *pit;
                cnt1.erase(pit);
                cnt2.erase(cnt2.lower_bound(seg2(pl, pr, pv)));
                nl = min(nl, pl), nr = max(nr, pr);

                nl = min(nl, l), nr = max(nr, r), nv = max(nv, v);
                cnt1.emplace(nl, nr, nv);
                cnt2.emplace(nl, nr, nv);
            } else {
                if (pit->v < it->v) it = pit;
                auto [nl, nr, nv] = *it;
                cnt1.erase(it);
                cnt2.erase(cnt2.lower_bound(seg2(nl, nr, nv)));
                nl = min(nl, l), nr = max(nr, r), nv = max(nv, v);
                cnt1.emplace(nl, nr, nv);
                cnt2.emplace(nl, nr, nv);
            }
        }
    }
    cout << res << "\n";
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

G. The Median of the Median of the Median

先用对顶堆求出\(b\)数组。

然后我们可以二分答案,二分枚举\(x\),然后把\(b\)数组内小于等于\(x\)的比标记为\(1\)。然后用前缀和维护一下,当我需要计算\(c\)数组的时候就可以\(O(1)\)的计算出区间内总数和小于等于\(x\)的数量,因此可以判断出当前的\(c\)是否大于等于\(x\)。然后我们在统计\(c\)种大于等于\(x\)的个数,如果超过了一半,说明中位数大于等于\(x\)。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;

struct Median {
    int m, n;
    priority_queue<int> l;
    priority_queue<int, vi, greater<>> r;

    Median() {
        n = m = 0;
    }

    void insert(int x) {
        n++;
        if (n == 1) {
            m = x;
            return;
        }
        if (x <= m) l.push(x);
        else r.push(x);
        int t = (n + 1) / 2 - 1;
        while (l.size() > t) {
            r.push(m), m = l.top(), l.pop();
        }
        while (l.size() < t) {
            l.push(m), m = r.top(), r.pop();
        }
    }

};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vi a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    vector b(n + 1, vi(n + 1));
    for (int i = 1; i <= n; i++) {
        Median median;
        for (int j = i; j <= n; j++) {
            median.insert(a[j]);
            b[i][j] = median.m;
        }
    }
    auto t = [](int k) {
        k = (1 + k) * k / 2;
        return (k + 1) / 2;
    };
    auto check = [&](int x) -> bool {
        vector c(n + 2, vi(n + 2));
        for (int j = 1; j <= n; j++)
            for (int i = j; i >= 1; i--)
                c[i][j] = (b[i][j] <= x) + c[i + 1][j];

        int cnt = 0;
        for (int l = 1; l <= n; l++)
            for (int r = l, sum = 0; r <= n; r++) {
                sum += c[l][r];
                if (sum >= t(r - l + 1))
                    cnt++;
            }
        return cnt >= t(n);
    };
    int l = 1, r = 1e9, res = -1;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) res = mid, r = mid - 1;
        else l = mid + 1;
    }
    cout << res;
    return 0;
}

M. Find the Easiest Problem

map<string,set<string>>统计一下每道题目的通过人数就好了。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

void solve() {
    int n;
    cin >> n;
    map<string, set<string>> cnt;
    for (string team, problem, result; n; n--) {
        cin >> team >> problem >> result;
        if (result != "accepted") continue;
        cnt[problem].insert(team);
    }
    string res;
    int val = 0;
    for (auto [i, v]: cnt) {
        if (v.size() > val) val = v.size(), res = i;
    }
    cout << res << "\n";
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

标签:nl,Contest,int,Asia,ICPC,cnt2,cnt1,nr,nv
From: https://www.cnblogs.com/PHarr/p/18417549

相关文章

  • ICPC网络预选赛 I 游记
    周四去北京参加了个qrt宣讲。晚上经典杨卓凡在arxivagent文章里面找数学公式,一个也没找到。我点开agenttuning60个citation文章他问我有多少不是灌水,我将信将疑说0?周五早上出了个o1-preview,用它20刀能跑通一个jericho游戏。炸裂!晚上在东升大厦开组会,组会上就差把......
  • AtCoder Beginner Contest 371
    A-Jiro输入\(AB,BC,AC\)的大小关系,输出中位数。手动模拟一下。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglongintread(){intx=0;boolf=false;charc=getchar();while(c<'......
  • 2020 ICPC 上海赛区
    赛时6题。第七题我写的没de出来(给队友跪了)xixike哥太强了有5题代码都是他写的(我只写了半题)ggxxdd哥也非常强特别会数学题。只有我什么都不会G,B都是队友切的签到,没看M:虽然会有重复的,但只要把前缀一起放到map里去就不会有任何重复的点因此可以打标记,这样就能建树了。然后就是......
  • The 17th Heilongjiang Provincial Collegiate Programming Contest A(思维 + 二分)
    题意有\(n\)本类型\(A\)的书题解点击查看代码#include<bits/stdc++.h>usingi64=longlong;voidsolve(){ inta,b,n,m,h; std::cin>>a>>b>>n>>m>>h; i64cnt=i64(n/b)*(h-a); if(cnt>=m-1)......
  • 2024ICPC网络赛第一场题解(部分)
    这一场基本纯挂件,给队友翻译翻译题面,帮队友打打板子了,可惜最后40sL题冲了一个\(O(\frac{n^3}{w})\)的bitset最后wa了,所以下面的题解我也只能看着队友代码说说大概,主要参考一下代码吧。A题意给出32个队伍的能力值,和比赛的规则,其中中国队是第一个队伍,问所有分组的情况下,中国队......
  • AtCoder Beginner Contest 371
    A-Jiro(abc371A)题目大意三个人,给定他们相互之间的大小关系。问谁在中间。解题思路排个序,大小结果就是题目给的,因为问的是中间是谁,所以写的时候并没在意是升序排还是降序排。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmai......
  • AtCoder Beginner Contest 371
    ABC371总结AtCoderBeginnerContest371一些废话想着以后换一种方式写总结,不再以那种题解形式,写起来又累又难写,只对其中部分有意思的题目写出完整的题解。就是以随笔的形式,在打完比赛后写出自己的一些感悟,每道题做的过程中的一些思路、用时和需要改进的地方,就是类似随笔之类的......
  • AtCoder Beginner Contest 371
    https://atcoder.jp/contests/abc371C:暴力。思路是把1-8的点映射到全排列上面,然后把有的点去掉没的点加上取ans最小值。这题复杂度是\(8!\times7\times4\),暴力求全排列即可(第一次写暴力全排列思索了一会复杂度#include<bits/stdc++.h>usingnamespacestd;#definepiipai......
  • P9891 [ICPC2018 Qingdao R] Repair the Artwork 题解
    所求即为选择的区间恰好包含所有\(a_i=2\)的位置的方案数。设所有\(a_i=2\)的位置\(i\)组成集合\(S\),考虑容斥被选中的位置是\(S\)的子集的方案数\(g(S)\)。设\(T\)为\(S\)的子集,\(T\)的贡献\(f(T)\)为:选中的位置都在\(T\)的子集中的方案数乘容斥系数\(......
  • Flink Forward Asia 2024 议题征集令|探索实时计算新边界
    简介:FlinkForwardAsia2024将于11月29日至30日在上海举行,现公开征集议题。作为ApacheFlink社区的重要年度活动,大会旨在汇集行业最佳实践和技术动态。议题覆盖流式湖仓、流批一体、Al大模型、生产实践等方向,并特别关注ApachePaimon和FlinkCDC等社区项目。所有议题将由专......