首页 > 其他分享 >Codeforces Round 977 (Div. 2)

Codeforces Round 977 (Div. 2)

时间:2024-10-06 21:37:10浏览次数:9  
标签:977 int Codeforces 序列 num 操作者 物品 操作 Div

手速局,因为水平不够三题遗憾离场。

A. Meaning Mean

题意

你一个序列,你每次可以选择两个数删掉,并把他们的平均数加入到序列的末尾。当序列长度为 \(1\) 的时候,剩下的数最大值是多少。

思路

当时比赛的时候唐了,耽误了好几分钟。想的是先奇数和奇数相加,偶数和偶数相加,这样能避免下取整的时候 \(-1\) 。其实每次选择序列里两个最小的数操作就可以了,因为每次操作相当于把两个数除 \(2\) ,所以尽量的让大数除的少就能保证最后剩下的数最大。

代码

void solve()
{
    int n;
    cin>>n;
    priority_queue<int,vector<int>,greater<int>> q;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        q.push(x);
    }
    while(q.size()!=1)
    {
        int x=q.top();q.pop();
        int y=q.top();q.pop();
        q.push((x+y)/2);
    }
    cout<<q.top()<<endl;
}

B. Maximize Mex

题意

给你一个序列和一个 \(x\) ,你可以进行任意次操作令 \(a_i:=a_i+x\) 。问你以最优方式操作序列的 \(MEX\) 最大是多少。

题意

一般求 \(MEX\) 我都会开个桶来记录一下每个数出现了多少次,从小到大遍历第一个没有出现的数就是 \(MEX\) 。这个题也是同理,如果有多个相同的数那么只有一个数能产生贡献,然后让剩下的都加上 \(x\) 即可。

代码

void solve()
{
    int n,m;
    cin>>n>>m;
    vector<int> num(n+2);
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        if(x>n) continue;
        num[x]++;
    }
    for(int i=0;i<=n+1;i++)
    {
        if(!num[i]) {cout<<i<<endl;return;}
        num[i]--;
        if(i+m<=n) num[i+m]+=num[i];
        num[i]=0;
    }
}

C1. Adjust The Presentation (Easy Version)

题意

给你一个长度为 \(n\) 的操作者的顺序 \(a\),再给你一个长度为 \(m\) 规定了只能由谁操作的物品的顺序 \(b\) 。每个操作者操作完一次之后可以插入到队列中的任何位置。问你这 \(m\) 个物品能不能被对应的操作者操作完成。

思路

首先一个人如果操作完了它可以插入到队列的任何位置,说明他已经无敌了,如果当前被操作的物品指定的操作者排在后面并且他没有操作过任何物品,那么他无论如何也无法排到前面来操作,这个序列就不合法。如果这个物品对应的操作者已经操作过了,由于他可以去任何位置,那么这个物品就能立刻被操作。如果所有的物品都能被操作那这个序列就合法。

代码

using namespace std;
void solve()
{
    int n,m,q;
    cin>>n>>m>>q;
    vector<int> a(n+1),b(m+1);
    vector<int> vis(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++) cin>>b[i];
    int pos=1;
    for(int i=1;i<=m;i++)
    {  
        
        if(vis[b[i]]) continue;
        else if(a[pos]==b[i])
        {
            vis[a[pos]]=1;
            pos++;
            continue;
        }
        else {cout<<"TIDAK\n";return;}
    }
    cout<<"YA\n";
}

C2. Adjust The Presentation (Hard Version)

题意

在 \(\text{C1}\) 的基础上又添加了一个修改的操作。我有 \(q\) 次修改操作,每次修改可以更换一个物品指定的操作者(永久性操作),问你修改完了之后的序列是否还合法。

思路

如果一个人可以随意调换位置 (无敌了) 说明他已经操作过物品了,那么他最早能调换位置的时间就是第一个指定他为操作者物品的下标,即第一个 \(b_j=i\) 的下标 \(j\) 。那么每个人最早的无敌时间不能早于排在他前面的人的无敌时间。现在问题是怎么维护这个最早的无敌时间。
我们每次修改只会修改一个位置,那么他能影响到的之后他前面的位置,后面的位置和他自己。所以每次修改只需要更新这三个位置就行了。

代码

void solve()
{
    int n,m,q,num=0;
    cin>>n>>m>>q;
    vector<int> a(n+1),b(m+1),inv(n+1),s(n+1);
    vector<set<int>> times(n+1);//维护每个人最早无敌时间
    for(int i=1;i<=n;i++) cin>>a[i],inv[a[i]]=i;
    for(int i=1;i<=m;i++)
    {
        cin>>b[i];
        b[i]=inv[b[i]];
        times[b[i]].insert(i);
    }
    for(int i=1;i<=n;i++)
    {
        s[i]=times[i].empty()?m+1:*times[i].begin();//如果没有指定他操作的物品,那这个人的无敌时间就是正无穷
    }
    for(int i=1;i<n;i++) if(s[i]>s[i+1]) num++;//统计不合法的人的个数
    if(num) cout<<"TIDAK\n";
    else cout<<"YA\n";

    auto update=[&](int x,int c)
    {
        if(c==1) s[x]=times[x].empty()?m+1:*times[x].begin();
        if(x>1 && s[x-1]>s[x]) num+=c;
        if(x<n && s[x]>s[x+1]) num+=c;
    };

    while(q--)
    {
        int x,y;cin>>x>>y;
        y=inv[y];
        update(b[x],-1);//删掉这个位置的贡献
        times[b[x]].erase(x);
        update(b[x],1);//删掉之后更新无敌时间和不合法位置的个数
        b[x]=y;//修改
        update(b[x],-1);
        times[b[x]].insert(x);
        update(b[x],1);
        if(num) cout<<"TIDAK\n";
        else cout<<"YA\n";
    } 
}

标签:977,int,Codeforces,序列,num,操作者,物品,操作,Div
From: https://www.cnblogs.com/Lao-Die/p/18449435

相关文章

  • Codeforces Rund 977 div2 个人题解(A~E1)
    CodeforcesRund977div2个人题解(A,B,C1,C2,E1)Dashboard-CodeforcesRound977(Div.2,basedonCOMPFEST16-FinalRound)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#includ......
  • Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)
    CodeforcesRound977(Div.2,basedonCOMPFEST16-FinalRound)A.MeaningMean题目链接:Problem-A-Codeforces题目描述:给定一个包含(n)个正整数的数组(a)。你可以执行如下操作直到数组中只剩下一个元素:从数组中选择两个不同的元素(a_i)和(a_j......
  • CF 977 Review
    CF977Review掉大分了,我去,绿名也是可以掉分的,我去你简直太牛了sgh。我是真正的飞舞。A排序以后贪心或者直接优先队列模拟即可,都可以过。Code#include<bits/stdc++.h>usingnamespacestd;template<typenameT>inlinevoidre(T&x){ x=0;intf=1;charc=getchar(); wh......
  • 【CodeForces训练记录】Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final
    赛后反思做红温了,太菜了,每题都需要WA几次才能过,B题看到MEX选择性害怕,时间复杂度又算错了A题每次选择一对\(a_i,a_j\)把均值插入数组最后面,要想结果最大,对于两个数求均值,最后的结果一定是小于等于其中的较大值,我们可以考虑如何最大化最后一次操作,想到将最大值保留在最后再......
  • 组织: 阶级: 组织+管理+授权+组织结构设计+ 角色 + 分工: individual类型: 体力+普工+
    组织:阶级:组织+管理+授权+资源管理+组织结构设计+角色社会:教育分科+分工:individual类型:体力:普工:砖头,销售文职:上传下达,文书专业:一招鲜,专家管理:人精高管:人上人企业主:金富民官员:高官:分封贵族:家族尊贵,出生关系帝王:砖头:哪里需要哪里搬,价值:自我:社......
  • 自动滚动和循环内容DIV
    <!--HTMLVersionDeclaration--><!DOCTYPEhtml><!--HTMLRootElement--><html><!--HTMLHeadSection--><head><!--HTMLDocumentTitle--><title>ThisisTitle</title><stylety......
  • 2024.10.4 ROS第五章结束,复习背包问题模型 + codeforces刷刷题
    项目学习总结ROS第五章主要是学习了坐标变换,实际用途还是好理解的,比方说地面基地控制无人机追鸟。坐标变换主要是用tf这个包实现的。可以实现静态坐标变换,动态坐标变换和多坐标变换。静态和动态变换的关键函数:ps_out=buffer.transform(ps,"base_link");动态变换里面主要是......
  • Codeforces 杂题
    CF1994E\(*2000,\texttt{Tag:}\)贪心,位运算题意:给出一片森林,每次你可以选择一个点删去它的子树,求所有删去的子树大小的按位或结果的最大值。Solution按位或可以看做在二进制下的不进位加法,因此,若一棵树不管怎么拆分,它拆分出来的子树大小或的结果不会大于它本身。若一棵树......
  • 【处理元组有关的题型的技巧】codeforces 1677 A. Tokitsukaze and Strange Inequalit
    题意第一行输入一个正整数\(T(1\leqT\leq1000)\),代表共有\(T\)组测试用例,对于每组测试用例:第一行输入一个正整数\(n(4\leqn\leq5000)\),第二行输入\(n\)个正整数\(p_i(1\leqp_i\leqn)\)。对于\(1\leqi<j<k<l\leqn\),若有\(a_i<a_k,a_j>a_l\)成......
  • Codeforces2020D Connect the Dots(观察 + 并查集 + 差分)
    题意多组数据。数轴上有\(n\)个点,编号为\(1\simn\),对这些点做$m$次操作。每次操作给出三个整数\(a_i(1\lea_i\len)\\\d_i(1\led_i\le10)\\\k_i(0\lek_i\len)\)。将点\(a_i,a_i+d_i,a_i+2\timesd_i,a_i+3\timesd_i,\cdot\cdot\cdo......