CF2217E Definitely Larger 题解

题面链接

思路

作者一开始把题读漏了,没看着 p ,   q p,\,q p,q 都是 1 ∼ n 1\sim n 1∼n 排列,还在想着要处理 p p p 值相等的情况,于是直接卡死了。(应该没有人像我这样吧)

我们用 a i a_i ai 表示可能支配 i i i 的位置个数,初始值就是有几个 j > i j>i j>i 满足 p j > p i p_j>p_i pj>pi。从 1 1 1 开始从小往大往 q q q 里面填值。 在填 1 1 1 的时候, q q q 里面还没有值,未来也不可能有比 1 1 1 小的值,如果在 q i q_i qi 处填 1 1 1,所有 j > i ,   p j > p i j>i,\,p_j>p_i j>i,pj>pi 的都一定支配 i i i,所以必须满足 d i = a i d_i=a_i di=ai。我们要做的就是找到一个位置 d i = a i d_i=a_i di=ai,然后把 1 1 1 扔进去。

那如果有很多位置都相等呢?我们先来看看把 1 1 1 放进去之后有什么影响。由于这个位置一定比未来填写的位置要更小,不能再支配别人,所以它必须从 j < i ,   p j < p i j<i,\,p_j<p_i j<i,pj<pi 的 j j j 的可能支配位置中移除,这些 j j j 的 a j a_j aj 需要减一。对于其他位置就没有影响了。进行完这个操作之后,就可以填入 2 2 2,此时 2 2 2 是所有有影响的 q q q 值中最小的( q i = 1 q_i=1 qi=1 的位置对其他位置的影响已经通过把 a j a_j aj 减一消除了),就和上面填 1 1 1 的做法一样。接下来也能用一样的方法填入 3 ,   4 ,   5 , ... 3,\,4,\,5,\dots 3,4,5,...。

现在我们再考虑多个位置满足条件的情况。此时必须选择最前面的位置,如果选了不是最前面的位置 i i i,会把一些 j < i j<i j<i 的 a j a_j aj 减一,然而在 i i i 之前的一些 a j a_j aj 是和 d j d_j dj 相等的,那么减完之后 a j < d j a_j<d_j aj<dj。在整个过程中 a a a 单调不增,这样 a j a_j aj 就再也不可能等于 d j d_j dj 了,也不可能再有数填入位置 j j j,就无解了。

什么时候无解呢?上面提到过,如果出现一个 a i < d i a_i<d_i ai<di,就完蛋了。还有,如果找不到一个 a i = d i a_i=d_i ai=di,就是 a a a 都太大了,也无解。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
int t,n,p[5005],d[5005],a[5005],q[5005];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++) a[i]=q[i]=0;
		for(int i=1;i<=n;i++){
			cin>>p[i];
			for(int j=1;j<i;j++)
				if(p[j]<p[i]) a[j]++;
		}
		for(int i=1;i<=n;i++) cin>>d[i];
		bool succ=1;
		for(int i=1;i<=n;i++){
			int rec=0;
			for(int j=1;j<=n;j++){
				if(q[j]) continue;
				if(a[j]==d[j]){
					q[j]=i;
					rec=j;
					break;
				}
				if(a[j]<d[j]){
					succ=0;
					break;
				}
			}
			if(rec==0) succ=0;
			if(!succ) break;
			for(int j=1;j<rec;j++)
				if(p[j]<p[rec]) a[j]--;
		}
		if(succ){
			for(int i=1;i<=n;i++) cout<<q[i]<<' ';
			cout<<endl;
		}
		else cout<<"-1\n";
	}
}
相关推荐
王老师青少年编程7 小时前
2025年【江苏“信息与未来”编程思维】真题及题解(T2:坐标变换)
c++·题解·真题·坐标变换·编程思维·江苏·信息与未来
千寻xun7 小时前
一、理论篇-NVME协议学习笔记
笔记·学习·fpga开发·nvme ssd·nvme协议
CS创新实验室8 小时前
算法、齿轮与硅基大脑:数值计算发展简史
人工智能·算法·数值计算
海石10 小时前
1563分的简单题,可能就简单在能被暴力AC
算法·leetcode
海石10 小时前
1400分的dp汗流浃背之【交替子数组计数】
算法·leetcode
奋发向前wcx10 小时前
P2590 树的统计 题目解析
数据结构·算法·深度优先
2023自学中10 小时前
C++ 内存追踪器
linux·c++
imbackneverdie11 小时前
AI4S不止于分子药物:以MedPeer为代表的科研基建打开产业新增量
大数据·人工智能·算法·aigc·科研·学术·ai 4s
额鹅恶饿呃12 小时前
C语言中的数据结构和变量
c语言·数据结构·算法
Piko61412 小时前
锐捷 VSU 虚拟化堆叠配置
运维·网络·笔记