2024牛客多校训练营复盘:下篇(6~10)

牛客多校总帖子链接:https://ac.nowcoder.com/discuss/1295959

第六场:

名次:63

赛时:A B D F H I J (7题)

赛后:C


这场小武不在,我和zxn俩人做。

H 题是模拟抽卡,B 题找到结论之后马上就交,WA了一发,因为没有考虑到弦长大于n/2的时候相当于对称的短弦。

B 是 Cake2,过了之后发现有人交 Cake3 也就是 C 题,就去看。

结果我读错题了,丸辣!

原题是 “每个点属于 k 对 good pair” 我读成了 “整张图恰好有 k 对 good pair”。然后找了会儿规律发现,k 对 good pair 的图最多可以塞 9k 个点。于是找角度关系找了一会儿,写代码又写了一会儿,直接一个小时过去了。但看到没人过这题,想着能不能拿个一血,结果一交WA了,再仔细看看样例都过不去,就在窗口咨询出题人,出题人回复请认真读题。我一看,each candle is in,丸辣。

就这么完美浪费了一小时,期间zxn看了A。


A是个博弈,不过博弈的部分结论很简单,bob想让前缀0比例尽可能大,alice想尽可能小,于是可以变成一个在树上贪心走边的问题,只需要从下往上dp,分析当前每个位置的决策。zxn讲了好久我没听懂,就让他去写了。


D 题是个纯图论,我喜欢,轮边一定要在环上,切边一定不在环上,不知道为啥轮切俩字让我联想到蕉哥哥。这题做法也相当简单,先把轮边该删的删,再挨个儿加切边。

之后 F 题又是一个图论,给你一个森林,让你找一个排列满足相邻两个数没有边。我们发现除了菊花以外,所有的树都可以从叶子出发找到长为4的链,也就是说这种树深度大于等于4,我们可以先串偶数层再串奇数层。其他就是菊花,双点和单点三种情况,我和队友讨论了下,把双点也当菊花了,菊花加单点,怎么做。按照一个顺序,先花瓣,再单点,再花心,就可以了。


小武突然QQ说他会 I 了,于是 I 题交给他了,我帮他写了个对拍,拍出来好多次错误,但最后小武改对了。

本来只剩一小时了以为过 I 就行了,不过看到好多人过了 J ,就忍不住去看了。题面好长,输出好长。。。

本来大脑宕机不知道该往什么方向去想,但是队友发现这题其实老简单了,只需要保留编号最小的不可能被损坏的挖掘机,然后用2号挖掘机把所有非2的堆一起,最后用编号最小的再合一次就行。虽然有些小分类讨论,不过真不难写,思考难度也不大,属于是因为题面过长导致榜歪。


C 题真就人类智慧题,k = 1 是点对,k = 2 是多边形,k = 3 是一个类似卫星群的东西,且只有 4x 或 4x+2 的点数才有解,事实上zxn把 4x 的情况给想到了,不过没时间写了。

看题解发现有 4x+2 的构造法,不得不说人类的脑子真是太神奇辣。

赛后去补,发现 18 个点输出之后最后一个点便宜了好大的值,丸辣,怎么会事呢?我知道这题为了不卡精度,我把大环统一拆成4个一组的小环,k=2的情况也是拆成了三四五六边形,不敢往大的放,结果竟然18个点的卫星群就把我精度干爆炸了,三角函数精度有这么不堪吗?

后来慢慢查错,才发现我跟个神金一样。一开始为了避免半径过小引起计算错误,我看到题解里的半径大概是2,我就把二分的下限直接设成了2,谁知道半径刚刚比2小一点点,而题解的图里根本看不出来,而且我二分答案跑出来的半径也是2,我觉得这样的图半径就刚好是2了,我以为这就是数学之美,后来发现原来是因为我神金了。

第七场

名次:48

赛时:C D I J K(5题)

赛后:G H


这场好像出题组被骂的挺惨的?。。。

开场写了J,I 队友写的我没看,之后是 D 题,要求区间所有数字出现 k 次,我发现可以沿用染色的思路,最靠近当前位置的新颜色贡献+1,第k个位置-1,k+1的位置再加回1,这样就是求有多少区间的和等于0,同时0也是最小值,线段树维护最小值个数就可以了,第k个位置用vector存每个颜色比较方便。


写 D 时队友看了 K,是一个字符串题,问 T 同时出现在 S 子序列前缀和后缀的本质不同子序列数量。

我没参与,大概口胡下:找到前缀和后缀匹配的第一个T的位置,如果没交叉,那就前后都选上,中间随便选,求中间本质不同子序列个数(即使前后不全选也不会产生新情况,因为中间选的匹配T的字符可以平移到前面,相当于中间没选)

无论是否有交叉,都要考虑前后缀重叠的情况,发现只要有重叠,子序列一定是一个回文串,且回文中心决定了它的长度,判断T的每个字符能否成为回文中心即可。


本来在想要不要写 H 那个database,不过一直觉得自己复杂度有问题不敢写,于是咬咬牙开了最难蚌的 C 题。

C 题要写个并行排序,200 次 O(n) 交换排10000个数,可我们哪里听说过什么并行排序,就开始嗯搞。

尝试了归并,又尝试了递归,发现都没思路,我突发奇想问队友能不能猴子排序。

众所周知,冒泡排序循环 k 次可以把离目标位置距离小于 k 的所有数归位,那么我先猴子排序,是不是所有数离目标位置就会比较近。结果试了一下200次猴子,大部分数看起来是离的比较近了,不过写个checker发现离的最远的竟然有好几百,有时会上千。

就在我们觉得猴子排序没用时,队友提出了一个 k 冒泡的做法:既然一个一个数冒泡比较慢,那么每隔 k 个数进行比较,是不是所有的数回家会比较快呢?试了试100次猴子之后,k 从100取到2,进行100轮冒泡,发现结果不如人意,最远的数还是离了大几百。

zxn说我写的 k 冒泡有问题,应该每个k值运行3次,错位进行冒泡,分组向右移来保证每个数都和前面k个位置的数进行过比较。我改了之后,效果非常显著,跑了好几个随机数据,都能让最远的数限制在20左右,我们觉得已经稳了。

最后这题我们代码是三部分,第一部分60次猴子排序,第二部分100到2进行k冒泡,最后再来40次普通冒泡,非常奇妙的算法,不会证明,但是能过。

估计这题大部分人还是搜到了并行排序的算法,像我们这样乱搞出来的队伍我觉得10个都算多。


赛后补题,补了 G 和 H。


H zxn说他想练练码力,于是交给他,第一天晚上写的代码T掉了,但是又看不出和题解写法有何不同,只能自己找点优化方式。

第二天终于把T掉的代码改过去了,只能说就算区域赛遇到这种一眼会写的题,我也不太敢上手写,看小武有没有这个自信了。


G 题赛时黄大爷他们队就过了,好强。题目一眼网络流,不过有个将边流量改小的操作,要跑好多次网络流,感觉不咋会了。结果赛后一看黄大爷代码就秒懂了,这就是在UESTC图论专题传承多年(只有两年)的平面图转对偶图科技,将最小割转成了最短路,而最短路修改某条边的长度,变大需要科技,变小只需要维护从 s 到所有点距离和所有点到 t 的距离就好了。那个变大的科技我搜到CF原题了,不过还没补,过几天必定补上。

里面对相邻两行连通区间进行连边的操作,和去年哈尔滨ccpc第五题很像,当时硬用vector按顺序计算上一行每一个块儿连接情况,记得挺难写还WA了一发。补这题时想到了更简单的写法,就是双指针判断第一行 i 和第二行 j 是否相连,无论是否相连,让右端点小的那一行指针挪动,这样不会漏掉任何连接情况,两个指针对称,非常好写:

for(ll l=1;l<h;l++) {
    ll j = 0, i = 0;
    while(1) {
        if(i==d[l].size() || j==d[l+1].size()) break;
        if(check(d[l][i], d[l+1][j])) add(d[l][i].id, d[l+1][j].id, 0);
        if(d[l][i].y<d[l+1][j].y) i++;
        else                      j++;
    }
}

第八场

名次:92

赛时:A E J K(4题)

赛后:D


打的最惨的一场,只过了4题,差点出前100。dXqwq是个大毒瘤(生气)


K 题签到,A 题最终状态是确定的,怎么判断每个数是否出现在集合中,队友想复杂了,想写个莫反上去,我觉得没必要,再想想发现只要枚举这个数的所有倍数,看看它们gcd是否为这个数即可。

E 题就是个枚举,要先求 n~n+100 的所有因子,再判断那 100 多种 S(m) 是否可行,我直接上了PR,理论可过,结果TLE了,找了半天复杂度瓶颈发现竟然是我写的龟速乘,改成int128就过了。题解是区间筛,这个可以保证复杂度,以为当因子大于100的时候,每个因子只属于区间的一个数,这和区间长度为 1 复杂度是一致的。


然后是构造三角形,要求一个长度为 n 的排列只有 m 个相邻 3 个数能构成三角形。人类智慧题,没什么好讲的,反正这题就是队友之间来回贡献了一点突破口,就解决了。

突破有两个比较关键的点,一是把区间分成3等份,按照小数放一组,大数放一组,组内按132的顺序来放,可以保证这一大段区间没有三角形。

第二个点是为了解决模3余数1或2的情况,我发现可以往所有数前面放一个数或两个数,这两个数也不会和 1 组成三角形。


然后没别的题了,只剩一个赛马娘可以开了,我读题读得很慢,感觉不如队友一半速度,但是掌握了大概需要记录的东西之后,早早开始写了。写到一半zxn提醒我不需要把所有变量记下来,可以直接用 a[0] 到 a[6] ,一开始我以为每个变量有不同的作用,后来发现不同的地方很少很少,只有 a[6] 有轻微不同,所以赶紧改了过来。

读题期间还咨询了玩赛马娘的舍友,他很热心地给我提供了B站的机制介绍视频,还问我要不要打电话咨询,我觉得没必要了,已经懂了题目意思了。

距离结束24分钟的时候我们交了第一发,WA,赶紧找错误,发现是算lv算错了。不过lv计算错误就是我们唯一能找到的错误了,之后就一直WA到了结束。

结束后包大爷QQ说把long double改double就对了,试了下还真是,我们气愤地以为std写挂了。

后来听了群里的聊天,明白了double能过是运气好,floor取整丢精度,要加eps判断,正确做法是全转整数计算,输出时再转回去。dX说本以为OI出身的选手对浮点数处理会敏感些的,发现自己还是经验太少了。

不过我还是比较抱怨验题组没有把double的错误做法验出来,出题组也没卡掉double,这导致了好多人靠运气过了。

但想想也没掉出100名,没那么气了,只能说涨涨经验。

第九场

名次:28

赛时:A B C G H I K(7题)

赛后:


很顺利地开题,名次很高,赛后也没补题。小武这场输出拉满。

A 题签完 K 题卡了好久,迫不得已只能过来一起 debug,发现各种怀疑不如怀疑自己,队友奇怪的写法滋生了奇怪的边界讨论,一道签到题贡献了5次罚时。

签完看 H,H 是凸包直径模板,zxn 有 cjj 的板子,直接一发过了。

期间小武也写完了 I ,一发过了,我没看题。


B 题,又是一个数字出现次数题,这个和第七场那个题有啥子区别嘛。。。题目稍微难了点,就是检验第七场那些队伍有没有认真补题。

这题最外层是个dp,需要求所有合法位置的dp和,与那一道题的唯一区别就是把线段树上的贡献改了,上一题是求数值最小的个数,这题是求数值最小的位置dp值之和,dp值要更新,所以需要写两个不一样的update函数,也不难写。


C 题我和zxn都不会推式子,小武用莫反推了个随机数据可做的做法,反手就给过了,我没补。

G 题一开始大伙都读不懂题面,后来小武发现这就是mc里的黏性活塞,反手又给过了,我没补。

队友tql,orz。名次还不错,如果没有签到题的5发罚时就更高了。

开心地去干饭了,不想补题。

第十场

名次:53

赛时:A B D F H K L(7题)

赛后:J


最后一场,最大的遗憾是和 zxn 一起搞了两个小时还是没把 J 搞出来。到现在还是没把握 J 题的具体难度,感觉真正按题解做法过的队伍并不多,可能更多的是想黄大爷那种线段树合并来做的。


因为通宵研究了三色绘恋解包,只吃了个早餐,午饭也没吃,十二点前睡了一个多小时,迷迷糊糊起来就开始一起做题了。


A 题看到发起投降四个字绷不住了。

B 题队友写的。

H 题是个感觉比较经典的扑克牌赌博玩法,感觉在哪里见过(小圆:梦里见过的样子)。我以为成环的最大步数会比较小,模拟了一下,结果不容乐观。一看榜竟然这么多人会做。小武直接猜了个结论,问我是不是初始牌数占比就是胜利概率,我想也没想直接肯定。虽然小武还是有点慌,但我已经写完交了,过了。

F 题 nxn 的网格里加点,保证不能三点一线,也就是每行都不超过两个点,最多也就2000个点存在。zxn 提供了个貌似 n^2log 的调和做法,虽然不会证,但是感觉显然没问题,就是实时维护可填的位置,毕竟不能填的位置是占大多数的,不能填的位置就只需要O(1)判断。能填的话就更新整个网格,复杂度感觉也不会超过 n^2log。

我写完 WA 了,zxn 直接一眼丁真问了句为什么没有求gcd,改完过了。

K 题好像也不难,队友写的,我只是简单听了个思路。


我去看 L 题了,我一看,这不是密码锁吗,会不会和我之前国庆集训练习的一道图论题idea重复。结果读完发现还真是,直接找到当时的代码,比着代码狂抄,写的很快。

这题有个小坑点,当密码只有一位的时候,移动距离需要同时考虑大小和奇偶,而当密码有两位的时候,就有了操作空间,距离只需要比较大小。


D 题队友讨论了下,他们对 k 不小于0.1感了兴趣,也就是说当前rating对下一次的影响占比不到九成,他们发现这样的话在大概根号次之后,你的初始rating就一点贡献都没有了,于是根据这个结论进行dp就可以了。


之后还剩下两个多小时,我们感觉天时地利人和,觉得能再过几个题。小武看 I 去了,我俩讨论 J 。

结果两边都卡了,小武那里是想假了,J 题是没思路就开始写,写了个随机化没有过。

J 题我们的思路和题解是比较相似的,哪些点有可能成为红树的根,我们就check一遍,由于check是O(n)的,我们代码复杂度不对,于是想到在这些可能的点里随机化几个点进行check。

实事证明这样的check是错误的,不过赛后下载了数据发现只要把所有可能的点check一遍,答案还是求对了的。

哪些点可能会成为根呢,我和zxn讨论的结果是,对于每一个横跨的黑边,根不能出现在红边的链上,只能在两边的子树上,我们对这些子树求个交集。事实上也不是很好求,我还要写个换根dp,还写了个倍增找 x 到祖先路径上倒数第二个点(题解说这个找点不需要倍增的log,可以O(n)预处理?不知道是什么黑科技)。

缩点的想法和题解也是一样的,同一个连通块要么所有点合法要么所有不合法,因为红边相当于就是黑边树的一个点分树(之前我以为红黑两棵树互为点分树,后来发现不对),点分树的根连向自己的一个儿子一定是合法的。连通块只要有一个点黑边度数和红边度数不一致,那么整个连通块都不合法。

但是有一个优化题解里没说,std里有,那就是只需要check一次,如果不合法直接输出-1,这个我还不会证明,我也不想证明,有点累了。不过以后可以多一个经验,就是当随机化都不可行的时候,再多猜一些结论,比如一个点可以代表所有的点之类的。

后记

整体来说,今年的发挥比去年要好很多,去年只有前两场做出了金牌题进了前60名,之后一直没进前100。今年虽然最后的总排名50多,不过一直稳在了100,总分还是比较可观的。

去年牛客基本是我和zxn两个人在打,廖一直在外面忙保研的事。今年小武加进来之后队伍数学方面的缺陷被弥补了。

对于我自己的话,因为多打了一年,寒假以及上学期CF也刷多了好多题,把gym上几个经典的23区域赛补到了金牌题,感觉代码的正确率上升了不少,一些经典的模型写的也更快了。上学期也是多刷了些多项式的题,牛客第五场也派上了很大的用场。

不足的地方,数论水平还是比较糟糕,很多数论题没能和小武讨论得上,基本是小武一个人开的。


今年牛客有很多题idea比较好,不过最大的收获还是把一些经典的应用,比如区间数字出现次数,根号分治,移动零点的理解,这些复习了一下,配套上每道题拓展的一些小技巧,以后能够更快地做出类似的题。

有一些惊艳到自己的题,比如推箱子的那道按边BFS和它的优化,和按根号分出大质数进行分组背包的那题。

LR开船过河那题也是拓展了下队伍的思维,锻炼了下脑筋急转弯,或者说转化题意的能力。


如果说学到新科技或者高级东西,感觉确实在牛客多校并不多,顶多让我学到了个多项式优化背包,但那也是队友已经会了的东西。

学新东西的话,我们学校每周三的毒瘤场真是学了好多东西,什么可持久化李超树,01trie维护sg函数。不过毒瘤场整合起来不太方便,且有些题已经单独写题解了,题目的链接也不好找了,就不写总结了。

杭电有三场是提前验的题,验完根本没补,后两场还没打,所以一篇就能总结完,明晚写。


希望今年区域赛能发挥好点吧,退役前还是想打一次EC的。

posted @ 2024-09-11 23:48  maple276  阅读(83)  评论(0编辑  收藏  举报