Codeforces Round 967 (Div. 2)

A. Make All Equal

思路:观察题目,其实不难发现,保留一种数字之后,删除操作就可以删除任意其余数字。因此我们只需桶排序出数量最多的那一个数字的数量 x,最后的答案就是 n - x

代码:

/*
 * @OJ:
 * @ID:
 * @Author: ZhangChao
 * @Date: 2024-08-15 17:35:14
 */
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331;
int cnt[N], n;
void solve()
{
    int T = 1;
    cin >> T;
    while (T--)
    {
        memset(cnt, 0, sizeof(cnt));
        int mx = 0;
        cin >> n;
        for (int i = 1, x; i <= n; i++)
        {
            cin >> x;
            cnt[x]++;
            mx = max(mx, cnt[x]);
        }
        cout <<  n - mx << endl;
    }
}
signed main()
{
    ios;
    solve();
    return 0;
}

B. Generate Permutation

思路:题目要求构造出任意一种符合条件的排列,要求两种打字机回车操作数相同。观察回车操作,我们发现对于 i,如果 i - 1 在其左边,第一台打字机需要执行一次回车操作,反之,第二台打字机需要执行一次。因此,我们对于 a1a2a3...an ,可以构造出 an-1...a2a1a3...an,可以证明这样的序列是符合条件的。

代码:

/*
 * @OJ:
 * @ID:
 * @Author: ZhangChao
 * @Date: 2024-08-15 17:35:14
 */
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331;
int n, a[N];
void solve()
{
    int T = 1;
    cin >> T;
    while (T--)
    {
        cin >> n;
        if (n % 2 == 0)
        {
            cout << -1 << endl;
        }
        else
        {
            int mid = n / 2 + 1;
            a[mid] = 1;
            int tmp = n - 1;
            int cnt = 1, num = 1;
            while (tmp)
            {
                a[mid + cnt] = ++num;
                a[mid - cnt] = ++num;
                cnt++;
                tmp -= 2;
            }
            for (int i = 1; i <= n; i++)
            {
                cout << a[i] <<" ";
            }
            cout << endl;
        }
    }
}
signed main()
{
    ios;
    solve();
    return 0;
}

C. Guess The Tree

思路:可以发现,查询 ab 将返回 ab 之间路径的中点。如果路径长度为奇数,则会返回两个中心节点中更靠近 a 的节点。因此,我们可以在 log 的时间复杂度下,找到 a 任意一边。

代码:交互题,代码省略。

D. Longest Max Min Subsequence

思路:可以想到贪心的去求解,不让假设我们所要构建的序列为 b,长度为 m,对于 bi,我们需要找到一个合适的范围 [a,b],满足对于 [b+1,n],序列 a 中不同元素的数量为 m - i 个。为了解决这个问题,我们引入 l 数组记录每个元素最后的坐标。由此,可以将范围中的 b 转化为 l1 - ln 中的最小值。同时,我们观察到 ab 都是非严格递增的。因此,可以借助优先队列或单调栈在 nlogn 的时间复杂度下解决。

代码:

/*
 * @OJ:
 * @ID:
 * @Author: ZhangChao
 * @Date: 2024-08-15 17:35:14
 */
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(0)
#define endl '\n'
#define pii pair<int, int>
#define debug(x) cout << "x = " << x << endl;
#define lowbit(x) (x & (-x))
using namespace std;
const int N = 5e5 + 5, P = 13331, INF = 1e15;
int l[N], a[N], n, b[N];
bool used[N];
struct node
{
    int val, idx;
    bool operator<(const node &u) const
    {
        if (val != u.val)
            return val < u.val;
        return idx > u.idx;
    }
};
void solve()
{
    int T = 1;
    cin >> T;
    while (T--)
    {
        priority_queue<int, vector<int>, greater<int>> lx;
        priority_queue<node> mx, mi;
        cin >> n;
        for (int i = 1; i <= n; i++)
            l[i] = INF,used[i] = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            l[a[i]] = i;
        }
        for (int i = 1; i <= n; i++)
        {
            lx.push(l[i]);
        }
        for (int i = 1; i <= lx.top(); i++)
        {
            mx.push({a[i], i});
            mi.push({-a[i], i});
        }
        int i = 1, cnt = 0;
        while (!mi.empty())
        {
            // 1. [i+1,minlx]
            if (!(cnt & 1))
            {
                b[++cnt] = mx.top().val;
                used[b[cnt]] = 1;
                i = mx.top().idx + 1;
                // mx.pop();
            }
            else
            {
                b[++cnt] = -mi.top().val;
                used[b[cnt]] = 1;
                i = mi.top().idx + 1;
                // mi.pop();
            }
            while (!lx.empty() && lx.top() != INF && used[a[lx.top()]])
            {
                int j = lx.top();
                lx.pop();
                for (int k = j + 1; k <= min(lx.top(), n); k++)
                {
                    mx.push({a[k], k});
                    mi.push({-a[k], k});
                }
            }
            while (!mx.empty() && (used[mx.top().val] || mx.top().idx < i))
                mx.pop();
            while (!mi.empty() && (used[-mi.top().val] || mi.top().idx < i))
                mi.pop();
        }
        cout << cnt << endl;
        for (int i = 1; i <= cnt; i++)
        {
            if (i == cnt)
                cout << b[i];
            else
                cout << b[i] << " ";
        }
        cout << endl;
    }
}
signed main()
{
    ios;
    solve();
    return 0;
}
posted @ 2024-08-21 00:26  xcuzc  阅读(500)  评论(0)    收藏  举报