NOIP2021 做题笔记

这次又被抓过去写noip2021了\(qaq\)

P7960 [NOIP2021] 报数

可以用类似于质数筛的方法筛一遍,做到 \(\mathcal O(\)值域\()\) 的预处理,以及 \(\mathcal O(1)\) 的查询。

P7961 [NOIP2021] 数列

这题数据小,考虑使用超大力dp。
\(dp[i][j][k][l]\) 为讨论到 \(S\) 的第 \(i\) 位(二进制下),确定了 \(a\) 序列前 \(k\) 个数,\(S\) 前面有 \(k\)\(1\),且从上一位进位过来的有 \(l\) 位,假设序列上有 \(o\)\(i\),则有方程:

\[dp[i+1][j+o][k+(o+l)\&1][(o+l)>>1]=dp[i][j][k][l]\times {v_i}^{o}\times C_{n-j}^t \]

暴力转移即可。

P7962 [NOIP2021] 方差

什么 \(dp\)?没听说过啊。
考虑到差分数组为单谷函数时方差最小,直接随机化shuffle差分数组搞定!

P7963 [NOIP2021] 棋局

极其恶心的数据结构题。
首先,对于 \(\rm case\ 1\sim8\),可以直接暴力。
而对于 \(\rm case\ 9\sim14\),可以写并查集维护。
接下来来到正解环节。
由于棋子是一个一个加入的,所以连通块是不断分割的,有点难以维护,不妨倒着处理。
我们先写一个并查集,用于维护互通道路组成的连通块,以及直行道路组成的连通块(这里横向和纵向分开处理,原因后面讲)。
这个并查集需要维护连通块的大小,以及块内的编号最大最小值。

那吃子怎么办呢?
如果是走互通道路,则对于每一个联通块,可以开一个线段树(当然要动态开点),把连通块周围能吃掉的棋子存进去(要分两个颜色维护),若是黑色棋子,查询能吃到的白色棋子的数量即可。

如果是普通或直行道路,那最多吃四个子,直接判断就行了。

当合并连通块时,可以将两个联通块的线段树也合并进去。

这里可以按照加入棋子的顺序离散化每个棋子的等级,使每个棋子的等级不同。

线段树:

但是这样还不够,因为有可能一个点可以同时从直行道路和互通道路走到。所以要去重。

考虑同一行/列的点是连续的,所以可以按两种方式编号(就是之前讲的横向纵向分开处理),再插到线段树里,去重的时候直接区间查询就行了。

首先是预处理环节:

接下来,首先是计算互通道路的贡献:

然后是直行道路:

最后是普通道路:

最后的最后,献上完整代码:

posted @   nagato__yuki  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示