NOI2022 VP寄

Day -?

由于我特别菜,去年 NOIP 寄成了 158,今年省选遇上疫情,分数线提到了 210,所以省选寄了,NOI2022 D 类梦也寄了。

8 月 26 日晚上拿到了两天的 pdf 和 day 1 的数据,准备 VP。

Day 1(8.23 -> 8.26)

时间:8 月 26 日 22:00 到 24:00,8 月 27 日 08:30 到 11:30,共 5 小时。

没有大样例的解决办法:

  • T1:前两个样例用题面上的,样例 3 用数据点 3,样例 4 用数据点 12。
  • T2:如果能想出来大于等于 40 分,就用 rand() 随机抽取样例 2、3、4。
  • T3:直接使用数据中的 grader.cppcount.h 进行交互,样例 1 用数据点 1,如需要样例 2、3、4 则在题目保证范围内随机抽取。

这样应该比较接近 NOI 现场赛的情况吧。

下面的时间都是指比赛进行的时间,即 0:00 到 5:00。

0:00。

大概看一下三道题,感觉 T1 是个 DS,T2 可能是寄数 DP 之类的题目,T3 不可做。

0:22 开 T1。

一开始想用栈维护操作 1、2 的末尾插入、删除操作,但是操作 4 两个栈无法快速合并,然后发现链表支持快速合并。

这时有了一个很 naive 的想法,权值线段树求绝对众数,操作 3、4 暴力合并。发现操作 3 寄了,操作 3 的“合并”只是在查询时合并,而且暴力合并复杂度爆炸。

分析一下发现 \(m\) 个序列整体的绝对众数必定是某个序列的绝对众数,然而并没有什么用。

然后手动造了几组数据,发现如果一个序列存在绝对众数,那么绝对众数必然等于中位数。有了这个关键结论,很快想出了 \(O(n \log^2 n)\) 的做法,并优化到了 \(O(n \log n)\)

0:58 开始写,发现 \(x_1 \cdots x_m\) 可以相同的大坑,这意味着 int 寄了。1:37 写完,1:44 debug 完成,过了所有样例。

这时我想去看 T2,但是发现大样例没有删除操作,有点担心 T1 寄掉,于是去把 T1 代码看一下。

发现操作 1 的链表插入操作 insert(x, m) 写成了 insert(x, y),改了过来,过了样例,避免了 \(100 \to 65\)。(我的链表存的是编号,如果没有操作 2,就不会用到链表尾,也就不会寄)

2:00 开 T2。

先看了一下数据范围,前 15 分是爆搜,测试点 4、5 是 \(O(n^2)\) 判断,可能是贪心或者 DP。测试点 6、7、8 有放石子操作,摆烂。

分析了一下爆搜的复杂度,担心过不了 15,可能要记忆化搜索。

然后想 \(O(n^2)\) 判断方法。想出了几个错误的贪心方法,都被叉掉了,DP 状态也设计不出来。

3:08 写完了记忆化搜索,过了样例 1。

开 T3。

先吐槽一下 T3 题面太长,还过于形式化。

搞懂了 MR 和 MC 操作分别是什么东西之后,写了个 \(O(n^2)\) 的换根 DP,过了样例 1。

然后试图想链的部分分,然而没想出来,大约 4:40 开摆。

最后几分钟看了一下前两题文件操作,再看一下 T2 的爆搜有没有寄,结果发现 for (int A = l[1]; A <= r[2]; ++A) 这种傻逼玩意儿,赶紧改一下,重测样例 1,过了。

咕分:\(100 + 15 + 10 = 125\),如果 T1 寄掉那就真的大寄了,T2、T3 也可能会寄。

下午测分,\(100 + 0 + 10 = 110\),T2 怎么寄了?然后发现我上传完 T2 数据之后交的是 code 而不是 submit 文件夹里的代码。交一下 submit 中的代码,15 分。

实际得分:\(100 + 15 + 10 = 125\),一分没挂。

Day 2 (8.25 -> 8.28)

8 月 28 日有了下发文件。

时间:8 月 28 日 22:00 到 23:30,8 月 29 日 8:00 到 11:30。

首先花 20 分钟看了一下三道题。

T1 题面明示哈希,T2 要最小化逆序对数,T3 直接开摆。

然后想 T1。最暴力的做法显然就是枚举 \(G\) 中删掉的点,再判断 \(G\)\(H\) 是否同构。良心出题人明示哈希,哈希显然是用来判断 \(G\)\(H\) 是否同构。

但是问题来了,树怎么哈希?我并没有学过树的哈希算法,我只学过字符串哈希。

那就转化成字符串哈希。树转序列显然用 DFS 序,每个位置的值设置为树上节点的子树大小,可以发现不同构的树转成的 size 序列一定不同。

但是同构的树不一定得到相同的 size 序列,因为子树的顺序不确定,那就把子节点按照子树哈希值(相当于字符串一段的哈希值)排序,然后拼接即可。

这样树哈希的复杂度是 \(O(n \log n)\),总复杂度是 \(O(T C_n^k n \log n)\),看一下数据范围,居然可以过 76 分。

那就先写吧。1:16 写完并通过样例 1、2、3,测试样例 4,结果过了很长时间还没跑出来,看一下数据发现确实跑不出来。跑了 712 秒,1:28 跑完了,结果是对的。

1:30 去看 T2。T2 钦定了一些区间的最小值,要求出最小的逆序对数。

首先有个显然的结论,只有在限制中出现过的值是有用的。所以可以离散化权值。

前 16 分显然是无脑暴力。然后去看性质 A,限制的权值只有 0 和 1。

一开始想出一个极其傻逼的 \(O(n^3)\) DP,但是分数太低了,就没写,继续想有没有 \(O(n^2)\) 或者 \(O(n \log n)\) 的做法。

观察到对于最小值为 1 的区间,相当于这个区间所有数都是 1。

对于最小值为 0 的区间,至少有一个位置必须是 0,既然要最小化逆序对数,很显然的贪心就是把 0 尽量往前面放,用二分 + 线段树可以求出最靠左的合法位置。

贪心确定放 0 的位置,处理一下区间相交的情况即可。

对于没有确定的位置,猜测这些数是单调不减的,然后二分 0 和 1 的分界点。

这时发现,有个锤子的单调性,所以只能暴力枚举分界,时间复杂度 \(O(n^2)\)

但是,发现从前往后把一个原来是 1 的位置改成 0,对答案的影响可以 \(O(1)\) 计算,只需要预处理 0 的后缀和、1 的前缀和就行了。

这样就有了一个 \(O(n \log^2 n)\) 的做法,可以得到 52 分。

对于 NOI T5 来说,52 分已经是相当可观的分数了,先写吧。从 2:53 写到了 3:50,写了 206 行代码,来实现这两个部分分。

T3 真的不想看了,想想 T1 的正解和 T2 的性质 B 吧。然而都没想出来。

最后 20 分钟检查一下代码,就开摆了。

咕分:\(76 + 52 + 0 = 128\)

实际得分:\(76 + 52 + 0 = 128\)

两天总分:\(125 + 128 = 253\),加上笔试的 100 分就是 353。

Au 403,Ag 293,Cu 247。

NOI2022(F 类) vp Ag。

放到 NOI2022 的榜里面是 rk117,远远超过预期,我今年 NOI(F 类) 的目标就是达到 Ag 线。

但毕竟这是 vp,没有现场比赛的那种紧张感,如果是现场比赛,我也不知道能不能得到这么多分,可能因为比较紧张会挂掉一些分吧。

但就算 Day1 的 T1 和 T2 同时挂掉,没有发现 bug,那就会挂掉 \(35 + 15 = 50\) 分,那就是 303 分,也能 Ag。

update:看了下发文件,Day1 T2 的样例 2 能测出问题。

Day 3~4 (8.29~8.30)

补题,补了 T4、T5、T2,T3 和 T6 开摆了。

posted @ 2022-08-27 22:50  猫猫NOIP2006  阅读(194)  评论(0)    收藏  举报