CF1768C 题解

Posted chifan-duck

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1768C 题解相关的知识,希望对你有一定的参考价值。

考虑构造。

首先第一轮构造我们把第一次出现的数放到 \\(p\\) 里面,第二次出现的放到 \\(q\\) 里面。如果有数第三次出现呢?那么显然无解。

那么现在 \\(p\\)\\(q\\) 中都填了一些数,但是因为题目要求,所以填后面某个位置的数时要比这个位置已经填的数小所以把排列中没有的数存起来,按照从小到大的顺序填入即可,填的时候优先填入另一个排列对应位置较小的位置即可。显然,这是一种贪心的构造。

那么注意好代码实现就好,不要像我调了半个小时

#include<bits/stdc++.h>
//#define int long long
//#define lowbit(x) (x&-(x))
using namespace std;
const int maxn = 2e5+10;
int t;
int a[maxn],cnt[maxn];
int p[maxn],q[maxn];
int Search[maxn][2];
void work()
	int n;
	int flag=0;
	stack<int> op;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
		Search[i][0]=Search[i][1]=p[i]=q[i]=cnt[i]=0;
	
	for(int i=1;i<=n;i++)	
		if(cnt[a[i]]==2)
			cout<<"NO\\n";
			return ;
			
		if(cnt[a[i]]==0)
			p[i]=a[i];
			Search[a[i]][0]=i;
		
		else
			flag=1;
			q[i]=a[i];
			Search[a[i]][1]=i;
		
		cnt[a[i]]++;
	
	if(flag==0)
		cout<<"YES\\n";
		for(int i=1;i<=n;i++)
			cout<<a[i]<<\' \';
		
		cout<<\'\\n\';
		for(int i=1;i<=n;i++)
			cout<<a[i]<<\' \';
		
		cout<<\'\\n\';
		return ;
	
	for(int i=1;i<=n;i++) cnt[i]=0;
	for(int i=1;i<=n;i++)
		cnt[p[i]]++;
	
	for(int i=n;i>=1;i--)
		if(cnt[i]==0)
			op.push(i);
		
	
	for(int i=1;i<=n;i++)
		if(p[Search[i][1]]==0)
			p[Search[i][1]]=op.top();
			op.pop();
		
	
	for(int i=1;i<=n;i++)
		cnt[i]=0;
	
	for(int i=1;i<=n;i++)
		cnt[q[i]]++;
	
	for(int i=1;i<=n;i++)
		if(cnt[i]==0)
			op.push(i);
	
	for(int i=1;i<=n;i++)
		if(q[Search[i][0]]==0)
			q[Search[i][0]]=op.top();
			op.pop();
		
	
	for(int i=1;i<=n;i++)
		if(max(p[i],q[i])!=a[i])
			cout<<"NO\\n";
			return ;
		
	
	cout<<"YES\\n";
	for(int i=1;i<=n;i++)
		cout<<p[i]<<\' \';
	
	cout<<\'\\n\';
	for(int i=1;i<=n;i++)
		cout<<q[i]<<\' \';
	
	cout<<\'\\n\';

int main()
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
	work();


return 0;


以上是关于CF1768C 题解的主要内容,如果未能解决你的问题,请参考以下文章

题解CF519E

题解-比赛CF1332

CF398B题解

CF1354&CF1355 简要题解

题解 CF359D

CF1051G 题解