首页 > 其他分享 >CF#842-div2-C

CF#842-div2-C

时间:2023-01-07 21:44:07浏览次数:47  
标签:842 填入 int CF 构造 pair 序列 -- div2

题意

给定一个序列 A ,让你构造两个序列 B C 满足:
\(max(B[i],C[i])=A[i]\)
能构造输出YES然后输出两个构造序列BC,不能构造输出NO

题解

显然,我想到如果A序列中出现三个及以上的相同的一个数,必错。因为两个序列使某下标位置保持最大值最多只能出现两次。
既然已知NO的情况,下面来想如何构造。
我想的是分“无重复”和“有重复”两种情况讨论,其实可以归纳为一种情况。
即枚举A,未重复出现过放到B中,重复出现过的放到C中,此时已经构造出了部分序列。
剩下的位置,采用未填入的值用可以填入的最大值的策略填充。

具体说明未填入的值用可以填入的最大值

首先通过pair<int,int>记录好空的位置另一个序列填入的值以及当前下标;
然后根据sort对pair中的first排序,排好备用;
通过visa[],visb[]数组记录当前序列中有哪些值;
然后根据priority_queue优先队列存遍历vis后不存在(要填的)那些值;
然后根据贪心策略,对每一个序列,先从大到小遍历需要填入的下标,然后把优先队列中的值填进去,因为需要填的一定是允许填入当前位置的,和最开始构造序列时填的最大值相关,所以一定能满足填入要求,完毕。
题外话,向pair中添加使用语句make_pair(,)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+100;
int a[N];
int cnt[N];
int p[N],q[N];
pii aa[N],bb[N];
int visa[N],visb[N];
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            visa[i]=0;
            visb[i]=0;
            cnt[i]=0;
        }
        vector<int> ve;
        int f=1;
        for(int i=1;i<=n;i++){
            cnt[a[i]]++;
            ve.push_back(a[i]);
            if(cnt[a[i]]>2){
                f=0;
                break;
            }
        }
        sort(ve.begin(),ve.end(),cmp);
        int now=n;
        for(int i=0;i<ve.size();i++){
            if(ve[i]>=now){
                now--;
            }else{
                f=0;
                break;
            }
        }
        if(!f){
            cout<<"NO\n";
        }else{
            cout<<"YES\n";
            vector<int> vp;
            int ida=0,idb=0;
            for(int i=1;i<=n;i++){
                if(cnt[a[i]]==1){
                    p[i]=a[i];
                    visa[a[i]]=1;
                    bb[++idb]=make_pair(a[i],i);
                    q[i]=0;
                }else{
                    p[i]=0;
                    visb[a[i]]=1;
                    q[i]=a[i];
                    aa[++ida]=make_pair(a[i],i);
                    vp.push_back(a[i]);
                    cnt[a[i]]--;
                }
            }
            if(!vp.size()){
                for(int i=1;i<=n;i++){
                    if(q[i]==0) q[i]=p[i];
                }
            }else{
				//未填
                sort(aa+1,aa+1+ida);
                sort(bb+1,bb+1+idb);
                priority_queue<int> qa,qb;
                for(int i=1;i<=n;i++){
                    if(!visa[i]){
                        qa.push(i);
                    }
                    if(!visb[i]){
                        qb.push(i);
                    }
                }
                for(int i=ida;i>=1;i--){
                    p[aa[i].second]=qa.top();
                    qa.pop();
                }
                for(int i=idb;i>=1;i--){
                    q[bb[i].second]=qb.top();
                    qb.pop();
                }
            }
            for(int i=1;i<=n;i++){
                cout<<p[i]<<" ";
            }
            cout<<"\n";
            for(int i=1;i<=n;i++){
                cout<<q[i]<<" ";
            }
            cout<<"\n";
        }
    }
	return 0;
}

标签:842,填入,int,CF,构造,pair,序列,--,div2
From: https://www.cnblogs.com/iuk11/p/17033614.html

相关文章

  • CF757G Can Bash Save the Day? (复健 Day 1)
    先差分为\(Q(r)-Q(l-1)\),\(Q(i)=\sum_{j=1}^{i}\operatorname{dis}(p_j,x)\)。树上在线路径优先考虑点分树,先想询问怎么做,我们记\(f_i\)为点分树上\(i\)点子树内所......
  • CF1007A 题解
    题目传送门题目分析贪心水题。首先将原数组从小往大排序,然后不难想到一个简单但会超时的思路,即对每个位置,向后找到一个比自己大的数进行搭配。然后是一个简单的小优化,......
  • CF1707E Replace
    *3500。把我吓到了,其实这题比较水,已经快做出来了。顺便一提CF怎么这么喜欢出ST表。二元组不好看,换成\(f:\text{Interval}\to\text{Interval}\)(首先对于同一个......
  • CF1779C Least Prefix Sum 题解
    可能更好的阅读体验题目传送门题目大意给定一个序列\(a\),长度\(n\)。每次操作可以把\(a_i\)变成\(-a_i\)。要求\(a\)做前缀和之后的序列\(s\)中最小值为\(s......
  • CF1032C Playing Piano
    CF1032CPlayingPiano-洛谷|计算机科学教育新生态(luogu.com.cn)。题目大意是:能否构造一个长度为\(n\)的值域为\([1,5]\)的整数序列,使得相邻两个数之间的大小......
  • Codeforces CF255C Almost Arithmetical Progression
    链接难度:\(1500\)有一个序列\(b_{1\simn}\)。你需要从中选出一个长度最长的子序列\(p_{1\simk}\),使其满足\(p_1=p_3=...=p_{\lceil\frac{k}{2}\rceil-1},p_2=p_4=......
  • 2023.1.6 (Codeforces Round #842 (Div. 2))
    A.GreatestConvexLinkhttps://codeforces.com/contest/1768/problem/ADescription求出最大的\(x(1\leqx<k)\),使得\(x!+(x-1)!\)是\(k\)的倍数。Soluti......
  • Codeforces Round #842 (Div. 2)
    CodeforcesRound#842(Div.2)https://codeforces.com/contest/1768好困,放完代码就跑路。A.GreatestConvex#include<bits/stdc++.h>usingnamespacestd;void......
  • Codeforces Round #842 (Div. 2)
    Preface唉现在这是是做稍微难点的SB题(指Div2正常场的CD难度)总是要犯病因此Rating上不去不说,比赛的时候连EF题面都没机会看一眼这场先是C交上去忘记本机调试的时候把数组......
  • Codeforces Round 842
    目录写在前面ABCDE写在最后写在前面仁王真好玩大太刀真好玩下辈子我还要玩大太刀[](https://pic.imgdb.cn/item/63b7fdb4be43e0d30ec2dccd.jpg)顺带吐槽一下,这什么排......