Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)

Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)

A. Meaning Mean

题目链接: Problem - A - Codeforces

题目描述:

给定一个包含 ( n ) 个正整数的数组 ( a )。你可以执行如下操作直到数组中只剩下一个元素:

  1. 从数组中选择两个不同的元素 ( a_i ) 和 ( a_j ),计算 ( \lfloor \frac{a_i + a_j}{2} \rfloor )(向下取整)。
    1. 将该值加入数组末尾,并移除选取的 ( a_i ) 和 ( a_j )。 要求找出经过所有操作后,数组中剩下的唯一元素 ( x ) 的最大可能值。

解题思路:

这是一个贪心问题。为了最大化最后一个元素的值,每次操作都应尽量选择值相近的两个元素进行计算。这样可以减少对中间值的损失,保持最终结果尽可能大。实现时,可以使用一个优先队列(堆)来维护数组元素,每次弹出两个最小值进行计算,直到只剩下一个元素。

C++代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define close ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

signed main()
{
    close;

    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        vector<long long> a(n);
        for (auto &x : a)
        {
            cin >> x;
        }
        priority_queue<long long, vector<long long>, std::greater<long long>> pq(a.begin(), a.end());
        while (pq.size() > 1)
        {
            long long first = pq.top();
            pq.pop();
            long long second = pq.top();
            pq.pop();
            long long new_val = (first + second) / 2;
            pq.push(new_val);
        }
        cout << pq.top() << endl;
    }
    return 0;
}

B. Maximize Mex

题目链接: Problem - B - Codeforces

题目描述:

给定一个包含 ( n ) 个正整数的数组 ( a ) 和一个整数 ( x )。你可以多次将数组中的任意元素加上 ( x )。要求计算数组的最大 (\operatorname{MEX}) 值。 (\operatorname{MEX}) 指的是数组中未出现的最小非负整数。

解题思路:

我们需要优化数组的 MEX 值。为了保证更高的 MEX,应该优先填充从 0 开始缺失的数值。每次尽量将小于 MEX 的元素通过加 ( x ) 的操作进行补全。可以通过计数数组记录出现的值,再逐个检查缺失的最小值即可。

C++代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define close ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

void solve()
{
    int n, x;
    cin >> n >> x;
    vector<int> cnt(n + 1, 0);
    for (int i = 0; i < n; ++i)
    {
        int a;
        cin >> a;
        if (a <= n)
        {
            cnt[a]++;
        }
    }
    for (int i; i < n + 1; ++i)
    {
        if (cnt[i] == 0)
        {
            cout << i << endl;
            return;
        }
        int tmp = cnt[i] - 1;
        if (i + x <= n)
        {
            cnt[i + x] += tmp;
        }
    }
}

signed main()
{
    close;
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

C1. Adjust The Presentation (Easy Version)

题目链接: Problem - C1 - Codeforces

题目描述:

有一个包含 ( n ) 名成员的团队准备展示一场幻灯片演示。幻灯片有 ( m ) 张,编号从 1 到 ( m )。每张幻灯片由当前站在队伍最前面的成员展示,展示后可以将该成员移动到队伍的任意位置。要求在一系列更新操作之后,确保队伍能够按照指定的成员顺序展示所有幻灯片。

解题思路:

这是一个模拟问题,每次更新后检查当前队伍顺序是否满足条件。可以使用队列来模拟成员的移动,逐次检查每个幻灯片是否能按要求展示。由于这是简单版本,我们只需要在每次更新后检查队伍状态。

C++代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define close ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

const int N = 2e5 + 5;
int T, n, a[N], m, q, b[N], s[N];

void solve()
{
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        s[i] = m + 1;
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> b[i];
    }
    for (int i = 1; i <= m; i++)
    {
        if (s[b[i]] == m + 1)
        {
            s[b[i]] = i;
        }
    }
    for (int i = 1; i < n; i++)
    {
        if (s[a[i]] > s[a[i + 1]])
        {
            cout << "TIDAK" << endl;
            return;
        }
    }
    cout << "YA" << endl;
}

signed main()
{
    close;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

C2. Adjust The Presentation (Hard Version)

题目链接: Problem - C2 - Codeforces

题目描述:

这是问题 C 的困难版。区别在于更新操作的数量增加,最多可达 2⋅1052 \cdot 10^52⋅105。在每次更新之后,同样需要判断队伍是否可以按照指定顺序展示幻灯片。

解题思路:

由于更新次数非常多,需要使用高效的数据结构来处理队伍状态变化。我们可以使用集合来快速维护每个成员展示幻灯片的顺序,通过比较前后顺序的关系,来判断更新后是否满足要求。需要在每次更新时高效地更新集合和状态。

C++代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define close ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

const int N = 2e5 + 1;
const int inf = 2e9;

int v[N], who[N];
int p[N], n;

set<int> st[N];
int ans;

void xiu(int id, int x, bool f, bool s)
{
    if (id != 1 && f)
    {
        int p1, p2;
        if (st[id - 1].size() == 0)
        {
            p1 = inf;
        }
        else
        {
            p1 = *st[id - 1].begin();
        }
        if (st[id].size() == 0)
        {
            p2 = inf;
        }
        else
        {
            p2 = *st[id].begin();
        }
        ans += x * (p1 > p2);
    }
    if (id != n && s)
    {
        int p1, p2;
        if (st[id].size() == 0)
        {
            p1 = inf;
        }
        else
        {
            p1 = *st[id].begin();
        }
        if (st[id + 1].size() == 0)
        {
            p2 = inf;
        }
        else
        {
            p2 = *st[id + 1].begin();
        }
        ans += x * (p1 > p2);
    }
}

void clear()
{
    for (int i = 1; i <= n; ++i)
    {
        st[i].clear();
    }
}

signed main()
{
    close;

    int t;

    cin >> t;
    while (t--)
    {
        int m, q, x, y;

        cin >> n >> m >> q;
        for (int i = 1; i <= n; ++i)
        {
            cin >> v[i];
            p[v[i]] = i;
        }
        for (int i = 1; i <= m; ++i)
        {
            cin >> who[i];
            st[p[who[i]]].insert(i);
        }
        ans = 0;
        for (int i = 2; i <= n; ++i)
        {
            int p1, p2;
            if (st[i - 1].size() == 0)
            {
                p1 = inf;
            }
            else
            {
                p1 = *st[i - 1].begin();
            }
            if (st[i].size() == 0)
            {
                p2 = inf;
            }
            else
            {
                p2 = *st[i].begin();
            }
            ans += (p1 > p2);
        }

        if (ans == 0)
        {
            cout << "YA" << endl;
        }
        else
        {
            cout << "TIDAK" << endl;
        }

        while (q--)
        {
            cin >> x >> y;

            int id1 = p[who[x]], id2 = p[y];
            xiu(id1, -1, true, true);
            xiu(id2, -1, (id1 != id2 - 1), (id1 != id2 + 1));
            st[id1].erase(x);

            who[x] = y;
            st[id2].insert(x);
            xiu(id1, +1, true, true);
            xiu(id2, +1, (id1 != id2 - 1), (id1 != id2 + 1));

            if (ans == 0)
            {
                cout << "YA" << endl;
            }
            else
            {
                cout << "TIDAK" << endl;
            }
        }

        clear();
    }
    return 0;
}

抱歉,根据提供的引用内容,我无法理解你具体想要问什么问题。请提供更清晰明确的问题,我将竭诚为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【CodeforcesCodeforces Round 865 (Div. 2) (补赛)](https://blog.csdn.net/t_mod/article/details/130104033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值