【2023年成都七中NOIP联赛】游记

Day 1:

8:30:

睡懒觉,一觉睡到 8:30,“嘟嘟嘟”的电话声响起,迷迷糊糊睁开眼睛,快点,去成都七中……

没错,我连今天要考试都不知道(其实昨天老师给我发了消息的,只不过在学数学,没看),于是,坐出租车,一个人火速赶去……

路上可真堵,头昏昏的,想睡觉。

10:10

下车,进校门,直登 5 楼(不过是坐电梯),进了机房,人挺多啊,目测 50 人以上,找个靠窗户的位置坐下。

先看题,总共 4 题,T1 是个构造题,T2 看数据范围应该是个 DP,T3 看这题目背景应该是个模板(脑袋仔细回想了一会儿,嗯对,没学过),T4 跟区间有关系,目测是个线段树。

看题+理解题意耗时 20 分钟。

10:30

权衡了一下,先写 T4,其题目大意是:

给出一个序列,然后给出多个询问,每个询问给出多个区间,每一个区间求范围内的最小公倍数,然后输出这些区间答案的最小公倍数。(答案对998244353取模)

看起来很绕,其实比较好理解, 我的初始思路是:直接维护一个线段树,每个节点存的是区间的最小公倍数,嗯对,就这么 easy!

看了看数据范围,诶,线段树貌似可以直接 A 掉这题,嗯对,样例过了,大样例呢?找了半天没找到,等老师过来传一下。

11:00

T4 写完了,准备写 T1,是个构造题,题意如下:

有多个骰子,每面都有一个正整数(在 [0, 10^6 ] 以内),每个骰子的六个面上数字两两不同,然后在给出一个正整数 k,要求同时投出所有骰子,所有骰子朝上面上写有数字的异或和都是 k 的倍数。(要求构造每一个骰子上面的数字)

 看到异或了,可以考虑每一位的贡献,感觉可以 Trie 树来拆位考虑,写了 20 多分钟,后面发现,构造序列之后,验证答案的时间复杂度是 O(6^n),直接就爆掉了,感觉分还不如根据性质分类讨论分多,连忙删掉代码,考虑重构……

发现测试数据集 1 满足 n = 1,有着 10 分,这样直接输出 k 的倍数就行,但是得特判一点儿,k 的 6 倍如果大于 10^6,那么也是不满足的。

然后还有一个数据集满足 k = 2,想了想,2 的二进制位为 10,感觉可以 1 2 的直接输出。

这样好像 30pts 了,看 T2。

11:35

老师回机房了,过去要大样例,回过头来看 T4,测了一下,诶,怎么不对!调试了几分钟,猛然醒悟:

\operatorname{lcm}(a,b) \bmod p =\operatorname{lcm}(a) \bmod p+\operatorname{lcm}(b) \mod p

这个式子是并不成立的,对于取模后的结果,再取最小公倍数,有大概率是错的,就像:

(a/b) \bmod p=(a \bmod p)/(b \bmod p)

上述的式子一样,除法也是不成立的,在这种情况下我们可以用费马小定理或者扩展欧几里得(exgcd)来求逆元,使得等式成立,但是对于求 lcm 的情况,逆元貌似莫得用,想不到什么好的办法,就觉得不用改了,希望能骗点儿分。

然后再看 T2,不过 11:50 就交了,感觉这点儿时间推不出来 DP 的式子,于是转手开始打暴力,题意大概是这样:

有着一个长度为 n 的序列,每一个数字 ci 表示这种颜色,可以将这个序列给切开(想多少段就多少段),然后求这切开后序列的最大美丽值,以及切最大的段数,以及每段的起点和终点。(一个序列的美丽值为每段的 mex 之和)

一个集合 S 的 mex 定义为最小的没有在 S 中出现的非负整数。

数据范围挺大的 50 万级别的 n,数据好像不是捆绑测试,那行,对于 n <= 22 的数据,直接爆搜,看是否从此点切开,每次有两种选择,复杂度为 O(2^n),加了点玄学剪枝。

然后看数据,有个测试集为 ai<=1,这样每段我们求 mex 会发现,如果这一段既有 0,又有 1,那么贡献将是 2,所以 1 我们尽量选连续的 1 使得贡献为 0,因为选了 1 之后没选 0 的话贡献是 0,这样就少了。

所以我们尽量多选 0 和 1 在一起,否则不选 1,只选 0,这是考场策略,不过样例集里好似没有这个特殊性质的,所以自己手推一下就收尾了。

11:50

老师已经喊收卷了,T3 一行代码都没敲,因为题目要求不是捆绑测试,而且输出是 YES 或者 NO,不过 YES 要多输出路径的并(这个等会儿讲),所以直接一个 puts("NO") 结束。

嗯,考了一个半小时,收拾东西,出去吃饭。

12:10

领队老师带我们去了附近一家很火的面馆,我点了一个二两面,结果端出来一看,就这么点儿,只够垫点儿肚子的,然后看了看学长点的三两,额,跟我们家那边一两差不多,还贵了 8 块钱(这里小小的吐槽一下)。

吃了几下,就干完了,立马“杀”向机房,准备改题,结果一问,结果还没有出来,于是去做了做线段树的题目。

14:00

机房巨佬 meatherm 匆匆忙忙的跑了回来,手上拿着 U 盘,将成绩与排名发给了所有人,打开一看,挖草,竟然有 4 人 AK 全场!

密密麻麻的人头,我人呢?Ctrl+f 网页搜索,啊,怎么跑后面去了,不是吧,怎么才 10 分!!!

连忙一看,啊这,就只有 T1 的 10pts,怎么会?

看 T1 的另外一个特殊性质点 k=2,发现因为每一个骰子的六面数字要相同,我这 1 2 有相同的,直接就给 WA 掉了。

然后看 T2 的特殊性质点,全部 WA 了,发现不能直接选 1 的连续区间,得在左右两边有 0 的情况下,保留左端点或者右端点,这样可以得到一个 2 的贡献。

然后看 T3,TMD,居然没有一个是 NO,数据里全部都是 YES,真的黑啊!

再看 T4,所有测试点都有超过 mod 的,线段树直接挂掉了,还不如直接高精度呢,这样子至少能有个 30pts。(其实我那也没时间写了)

14:30

由巨佬 meatherm 和 nch 进行讲题,同时,他俩也是 AK 的人之一,先讲 T1,说了一大堆,最后说很简单,代码几行就搞定了,有亿点点没听懂。

然后是 T2,讲了一种 dp 做法,感觉懂了,写了一个 n^2 的 dp,然后优化就没搞懂了。

之后先讲的 T4,首先就是说明了线段树做不了这题,然后考虑根号分治,然后进行分块,然后在分块里面再分块,然后就没有然后了……(我还是不懂啊!)

最后讲 T3,其实这题是个网络流问题(什么东东,没有学过的悲哀)……(听不懂)

好了,讲完了。

15:20

题目讲完以后,一题都不好改,那就干脆不改了,继续去做线段树的题目了。

然后写了一个线段树二分,险而又险,勉强卡过,然后就下课了……

Day 2:

今天做好了准备,只迟到来了 3 分钟到考场。

8:35

打开文件,先阅题,T1 的描述有些长,有些没看懂,T2 感觉应该是个数学题,T3 是变形模式下的最长上升子序列,T4 看到操作有“回到第 T 次操作后的状态”,感觉是可持久化的数组。

感觉 T3 好写一些,先写 T3。

9:00

T3 题意大概是这样的:

给出 n 个区间(li,ri),将 li 到 ri 的数字按照顺序加入数组,然后求这个数组的最长上升子序列。

看起来挺简单的,但是这 li 和 ri 都很大,如果暴力去做的话就好像只有 10pts,赶紧推式子,设 fi 表示数 i 结尾的最长上升子序列。,然后每次加入一个区间时,有三种情况:

  1. i > r:则没有转移
  2. i < l:fi + r - l +1
  3. l < i < l:fi + r - i

这样时间复杂度是 O(n * max(ri)) 的,过不了大样例(一直卡着), 但是应该能得 30pts,于是去看 T1。

9:30

T1 题意很长,有点儿绕:

有 n + 1 个通讯站是好的,有 k 个通讯站是坏的,每一个通讯站都有一个坐标 (xi,yi),编号从 0 到 n + k,好的通讯站可以传送信号(向同一个轴方向传播),也可以接受信号,坏的通讯站只能接受信号,不能传送信号,假设传播信号不需要时间,而接受信号要 1 的时间,0 号通讯站是主站,它可以制造信号,制造和传播信号需要 2 的时间,求 0 号主站将信号传播到多个询问的通讯站需要最少的时间是多少?

这题,我看了半天,才发现,这是一个图,对于一个轴的通讯站,进行连边的操作,这样就是一个图了,然后求 0 点到其他店的最短路径,不就是单源最短路径嘛,直接手写 dijstra 算法,时间复杂度为 O(n log n) ,这不直接就过掉一题了,然后看 T4。

10:20

T4 看起来也像一个模板,大意是:

有一颗 n 个节点的树,每一个节点有着 (Li,Ri,Vi) 这个三元组,有着 3 个操作,第一个就是将节点 x 号的 (Li,Ri,Vi) 变为 (Li`,Ri`,Vi`);

第二个操作是创建一个长度为 n 的序列 a(初始全 0),询问在以 x 号节点为根的子树中,对于第 i 个节点,将 a 序列的 Li 到 Ri 区间增加 Vi ,然后给出 a 序列中 L 到 R 区间的和。

第三个操作是回到第 T 次操作后的状态。

这题我可以直接按照题意,先建树,然后建一颗线段树维护 a 序列的区间,有着区间查询,区间加法等操作,在操作 2 时,我们可以深搜一遍树,找到 x 号节点,依次进行 add 的累加,在操作 1 时,可以直接 O(1) 时间在数组里进行修改。

对于操作 3,我的考场思路很暴力,记录一下第 k 次操作是否是 1 号操作(因为只有 1 号操作是会变的),如果是,再记录一下第 k 次操作的节点原来的权值([Li,Ri,Vi]),然后从当前操作开始,逐渐向 T 号操作遍历,如果有 1 号操作,就进行赋值。

这样就实现了此题了,中间线段树写废了一下,调试了一下,小样例过了,大样例一直卡着,估计超时了。

感觉这样也能拿 30pts 了,于是回过头来看 T2。

11:20

T2 描述很简单:

给定两个长度为 n 的序列 a,b,可以进行任意重排,求出最大字典序的 c,其中 c_i=(a_i+b_i) \bmod m

刚开始我先考虑只用重排序列 b,思路为,对于 ai,求出 m - a_i \bmod m 的值,然后在 b 中查找这个值(可以二分查找) ,这样组合起来可以凑成最大的字典序 c,然后我这样写小样例过了,大样例没有过,感觉写暴力(组合数为 C(n*2,n),暴力起来太大了)可能还没有我这样写这个只用重排 b 的快嘛。

于是考试结束,在机房窝了半个小时该题,干饭喽~

12:25

因为今天出来的时间比较晚,没有和学长们一起吃饭,于是,我前往了“汉堡王”,点了一个单人套餐,这总比吃面划算多了嘛~

13:10

回机房了,人很少,听别人聊天我才知道今天上午的考试是和杭二一起考,浙江很卷的,现在巨佬们正在评测。

中午跟 Neil_Qian 聊了会儿天,发现我的思路 T1 过不了,因为可能有许多点在同一行或同一列,这样的话复杂度降到了 O(n^2),这样应该是 90pts。

于是继续去练线段树的题目,静静等待成绩的公布。

15:00

巨佬 meatherm 回来了,经过评测,咱们成都七中最高分 198pts,由于评侧机的编译器版本过低,很多代码没有过编译,于是在调。

我又做了一道线段树的离散化题目,然后去看线段树的区间合并。

16:00

成绩出来了,这一看,惊呆我的下巴,不是吧,怎么只有 20 分?我一看 T1 有着 10pts,T2 爆 0,T3 也是 10pts,T4 爆 0。

T1 不是差点优化就正解了吗?怎么会是 10pts 呢?用测试数据试了一下,有环的情况下,竟然卡出了,后来一看,怎么会,后面看函数,写的是堆优化的 Dijstra 算法,发现堆开的是大根堆,在有环且权值一样的情况下,一直在环上走,emm……

然后是 T2,爆 0 不出我所料,不过 1 分都没有骗到,有点儿可惜……

T3 第一个样例点过了,第 2 个显示超时,是哪点没有优化到吧……

T4 我感觉应该能拿点分啊,结果显示的是运行时错误,好像是不能用 auto 这个东东。

然后发现前 30 名好像都被杭二霸榜了,最高的也是直接 AK 全场,然后第二名 380,去官网查了一下,人家才初二……

16:30

看题解,T1 说的思路和我的差不多,要考虑优化:

每一行和每一列建立一个虚点,然后在这一行或者列的点超对应行或者列的虚点连边,边权为 0;

虚点再向这一行或者列对应的点连边,边权为 1。

这样就实现了连边,但是边的条数仍然是级 n 别的。

T2 的贪心策略有些没看懂……

T3 的 DP 式子和我是一样的,但是有着一层优化,选了一个区间,就一定要选它的右端点,否则不是最优的,所以说结尾点 i 就只有 n 个,这样复杂度降到了 O(n^2),然后可以用线段树进行一个维护,复杂度降到了 O(n log n)。

T4 的题解看的我一脸懵逼,什么鬼,竟然要面对数编程,对于不同的数据,还有不同的算法,什么主席树啊,分块啊,散块啊,莫队啊……(我都不懂啊!不过我这样写确实能拿 30pts 的)

总结:

细节啊细节,一定要关注细节,一不小心,掉坑里面了,然后呢,本来的高分呢,瞬降,然后,不就无了?

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙星尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值