第七届日本最强学生程序员锦标赛(Atcoder beginner contest 474 c)

2026年9月6日,又是一个风和日丽的午后,我没有午睡,而是静静等待Atcoder第七届日本最强学生程序员锦标赛结束,然后趁着比赛完结做一下C题。老实说Atcoder beginner contest 的C题很少会考查一些计算机科学领域的专业算法,但是却有一定思考的深度,需要一些小的tricks才能解决,今天的这题就很有意思,我索性记录一下吧。
C - Remove and Append
Time Limit: 2 sec / Memory Limit: 1024 MiB
Score : 300 points

Problem Statement
You are given a permutation P=(P1,P2,...,PN) of (1,2,...,N).
For q=1,2,...,Q in this order, perform the following operation.
Remove the element with value a_q from P, and append it to the end of P.
Find the value of each element of P after performing the Q operations.

Constraints
1 <= N <= 2 x 10^5
1 <= Q <= 2 x 10^5
(P1,P2,...,PN) is a permutation of (1,2,...,N).
1 <= a_q <= N
All input values are integers.

Input
The input is given from Standard Input in the following format:

N Q
P1 P2 ... PN
a1
a2
...
aQ

Output
Output P1,P2,...,PN after performing the Q operations, in this order, separated by spaces, in one line.

分析:
此题的数据规模来到了10的五次方,如果直接使用Array的delete api,是肯定不行的,因为数组删除元素的时间复杂度是O(n)。因此我们先使用Hash1记录每个元素最开始的坐标,然后采取逆向思维的方式,倒序遍历q次操作后最后一个数字是什么,用Hash2记录它,并把q次操作中出现的元素从Hash1里删除。最后我们再把Hash1的键和Hash2的键的逆序拼接成一个Array输出即可。

n, q = gets.split.map(&:to_i)
in_p = gets.split.map(&:to_i)
h1 = {}
h2 = {}
(0...n).each do |i|
  h1[in_p[i]] = i
end
num = []
q.times do
  a = gets.to_i
  num << a
end
num.reverse_each do |i|
  unless h2.key?(i)
    h2[i] = 1
    h1.delete(i)
  end
end
puts (h1.keys + h2.keys.reverse).join(" ")
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容