这套题我组的,于是来发一下题解。
前言
由于要求出NOIP难度的题目(还是我听错要求了?),题目难度总体偏低…结果我出得比NOIP还简单…
按照CSP2019 day1的难度来的…T1是那种看完题目就会做的题…T2T3也比较简单…所以可以说是白送AK场了。
异或柚子 题解
搬题人:Panda_hu
前言
tag:结论+树状数组
原题链接:「eJOI2019」异或橙子 。
其实我并不清楚改成柚子合不合适
这题是用来送分的…希望是全员AC…
题外话:其实大家可以试试eJOI的题…
UPD:由于换了T2,然后新的T2与T1算法重合了…所以这题也被换了[无奈]。大家有时间可以做做这道水题…
算法
由于异或的消去律,我们只需要统计区间中的每个数被[l,r][l,r][l,r]的子区间覆盖了多少次即可。
然后你可以试着找找规律。
- 对于长度为偶数的区间,答案为
0
。 - 对于长度为奇数的区间,答案为与lll奇偶性相同的aia_iai?的异或和。
因此我们只需支持单点修改,询问区间的奇数位置/偶数位置操作即可。
显然我们可以用两个树状数组维护前缀异或和解决。
时间复杂度:O(nlog?n)O(n\log n)O(nlogn)
期望得分:100100100。
监控中心 题解
搬题人:Panda_hu
前言
tag:思维+树
原题:CodePlus 5 第5题/共8题
这题是猫鲲出给NOIP2018的题目,可能放在Day1 T2代码量比较大就被毙了…
题目挺简单的…但是数据很难造…数据生成器长度是标程的两倍…
本身CCC的范围是10710^7107的,但是我电脑太慢了生成数据要5min,于是就成了2×1062\times 10^62×106。
算法
官方题解已经发了。
火锅盛宴 题解
搬题人:Panda_hu
前言
tag:树状数组/线段树+优先队列
原题:「CodePlus 2017 12 月赛」火锅盛宴
比较有趣的数据结构题。
但是算法完全在NOIP范围内。
题解
算法一(针对测试点1)
我们可以暴力地维护锅所有锅内的食物,并暴力查询即可。
时间复杂度:O((n+Q)Q)O\left( \left( n+Q\right)Q\right)O((n+Q)Q)或O((n+Q)Qlog?n)O\left( \left( n+Q\right)Q\log{n}\right)O((n+Q)Qlogn)
期望得分:8分
一些想法
我们可以分别维护锅内(未熟)的食物和锅外(已熟)的食物。对于操作1,31,31,3和操作222的第一部分(判定是否有已熟的食物),我们可以在锅外查询;对于操作222的第二部分(求最近的熟食),我们可以在锅内查询。
算法二(针对测试点1-3)
对于锅内的每种食物,我们分别使用链表(或vector)维护,这样操作222查询和操作000插入的操作总复杂度是O(Q)O\left( Q\right)O(Q)。
对于锅内食物熟了的时间,我们发现对于每种食物,食物煮熟的顺序和食物被放入的顺序是相同的,于是我们每次事件前暴力维护每个链表即可。总复杂度为O(nQ)O\left( nQ\right)O(nQ)。
对于锅外的食物,我们用数组(即nnn个变量)维护。于是对于每种操作222的第二部分查询,我们可以用O(1)O\left( 1\right)O(1)的时间回答;对于操作1,31,31,3的查询,我们可以用O(n)O\left( n\right)O(n)的时间回答。
于是我们即可在O(nQ)O\left( nQ\right)O(nQ)的时间复杂度内完成此题。
期望得分:20分
算法三(针对测试点4-5)
我们发现每个食物的sss值均为111,也就是说在其被放入锅内后一个时刻即会被煮熟。而题目保证每一时刻最多只有一个事件,因此我们可以认为锅内没有食物。
于是我们只需要用树状数组维护锅外的食物,并支持树状数组上二分,即可轻松解决此题。(当然,我们也可以借助set,不过这可能会使你的程序有更大的常数)
时间复杂度:O(Qlog?n)O\left( Q\log{n}\right)O(Qlogn)
期望得分:16分
算法四(针对测试点4-7)
对于锅内,我们可以使用链表(或vector)维护;对于锅外,我们可以用树状数组维护。
由于所有食物sss值相同,所以所有食物被煮熟的顺序与它们被放入锅内的顺序一致,我们可以用指针维护下一个将要被煮熟的食物的位置,即可快速完成“从锅内到锅外”的操作。
时间复杂度:O(Qlogn)O\left( Qlog{n}\right)O(Qlogn)
期望得分:38分
算法五(针对测试点8-9)
我们发现不存在区间求和操作,于是我们同样适用链表(或vector)维护锅内,用multiset或map维护锅外即可。(这两个数据结构完美支持所有查询、修改操作)
对于食物被煮熟的顺序,我们可以额外使用一个priority_queue或堆来维护锅内的食物,其中关键字为食物被煮熟的时间。每次操作前,我们不断弹出堆顶,直到堆顶还未被煮熟为止,并将被弹出的食物加入锅外即可。
我们也可以将所有操作t0idt 0 idt0id拆分成222个操作:
- ttt时刻将食物ididid加入锅内。
- t+s[id]t+s[id]t+s[id]时刻将食物ididid从锅内取出,并加入锅外。
并将所有操作重新按时间顺序排序,然后依次执行。
时间复杂度:O(Qlogn+Q)O\left( Qlog{n+Q}\right)O(Qlogn+Q)
期望得分:14分
算法六(针对所有测试点)
结合算法五和支持二分功能的树状数组即是这道题目的标算。
时间复杂度:O(Qlogn+Q)O\left( Qlog{n+Q}\right)O(Qlogn+Q)
期望得分:100分
针对程序常数的说明
对于使用支持二分功能的树状数组、priority_queue以及multiset或map的程序,在实际运行速度上有着一些不同。这是因为前两个数据结构的常数远小于后二者。对于使用其他数据结构的程序,有可能同样会有不同程度的常数问题,选手也因此会得到96?10096-10096?100的分数(即有可能无法通过最后两个测试点)。
在实际测试中,上面提到的四种数据结构都可以获得100100100分。
中位数 题解
搬题人:Panda_hu
前言
tag:排序+链表
原题链接:「THUPC 2019」大碗宽面
这可能是大家CSP以后遇见的第一个链表题了吧…
原题没有部分分…数据又是我自己造的…
题解
算法1:测试点5
ni=1n_i=1ni?=1
中位数就是两个数中较小的一个数。
期望得分:5
算法2:测试点1-4
暴力
复杂度:O(m2n+mnlogn)O(m^2n+mnlogn)O(m2n+mnlogn)
期望得分:25
算法3:type=A
跟算法1差不多,只需要再判定中位数位置与较小的一个常数列的大小的大小关系即可。
期望得分:20
结合暴力可得35分。
算法4:type=B n≤1000
对于每个u,vu,vu,v,二分中位数,用等差数列通项公式判定即可。
期望得分:40
结合暴力可得50分。
再结合算法3可得55分。
算法5:type=B
这其实是用来引大家往正解方向想的。
考虑可以将u,vu,vu,v一起判断,然后你会很容易想到正解。
如果大家有做法可以来分享一下。
期望得分:50
结合暴力可得60分。
算法6:ni为偶数
满分做法的一部分,具体看下面。
期望得分:50
结合其他部分分以获得更高的分数。
算法7:满分做法
复杂度写错了…是O(m2+mmax?{ni})O(m^2+m\max\{n_i\})O(m2+mmax{
ni?})
期望得分:100
总结
大家一定AK地很开心:)