暑假后期模拟赛赛后总结
暑假过去了,简单总结一下吧。
可以说没有多少好好发挥的场次,主要原因是上午不在状态和没有遵循一套合理的考试策略。
上午的明显比下午晚上没精神,我也一直在调整。
考试策略问题,属于自己犯懒,不愿意去规划时间、不愿意写暴力,这是以后一定要避免的。
还是要把每场模拟赛用正式赛的态度去对待。
然后就是挂分问题,在简单题尤其明显,主要原因是没时间或者没办法对拍、题意理解偏差。
有时间一定要对拍,这属于重要的考试策略。平时写题还是要养成每一步都小心谨慎、考虑周全的习惯,能一遍写对当然是最好的。"think twice, code once."
8.16
T1
先想贪心,然后尝试用桶代替堆,可以做到 \(\mathcal O(nk)\)。
被卡常了只有 90 分。
T2
发现一个性质:每条链的两端一定是这条链的极值。然后 DP 即可。
T3
没补呢。这是一个哈密顿回路的形式,题解是说搜出来 \(5\times 5\) 的一些方案然后拼接。
T4
学傻了。发现在 \([l,r]\) 的 Border 不合法的话,在 \([l-1,r+1]\) 也不会合法。那么每次从上一次的答案长度 \(+2\) 开始枚举,类似 SA 求 \(\mathrm{Height}\) 数组,是 \(\mathcal O(n)\) 的。
8.17
今天有过于犯傻,挂了俩题。
T1
先考虑两个字符咋做,考虑分治,然后就是一正一负算贡献,用一个桶配对。
多个字符考虑大力记状态,只记录字符之间的相对大小,然后用 std::map 配对。复杂度 \(\mathcal O(n|\Sigma|\log^2 n)\),有点危但也跑过去了。其实可以哈希。
为什么别人随机化乱搞都能过。
T2
显然两类粒子任何时候不可能交叉,那么可以 \(k\) 次二分最早两类粒子接触的时间,然后删去,复杂度 \(\mathcal O(nk\log *)\)。
注意接触时刻的间隔可能小于 \(1\),考场二分写的整数直接挂成 5 分。
T3
考场莽了一个假的状压,没分。
直接三进制状压每个质因子出现 0 次 / 1 次 / 大于 1 次,每次只允许相交 1 个质因子,会有问题。如果存在若干出现 1 次的质因子属于同一个数,那么相交多个也是可行的。
那么状压质因子的集合划分,并新增两个虚点,与虚点 1 同一集合表示出现 0 次,与虚点 2 同一集合表示出现大于 1 次,然后转移就是对的了。
T4
整体二分板子。递归小于 \(\mathrm{mid}\) 的询问时忘记修改 \(k\),挂成 0 分了。
8.18
T1
模拟然后搜索。数字居然有超过 1 位的,被坑惨了。
T2
区间 DP 经典题。
T3
不考虑人之间互不相同的的限制的话,可以数位 DP。枚举最早的脱离限制的位(钦定一个所有人都具有的前缀),设 \(h(i,1/0,1/0)\) 表示 \(i\) 个人有奇 / 偶 个人选了 \(1\)、是 / 否有人选了 \(0\)、且异或和为 \(0\) 的方案数。
对于相同的前缀只有偶数个人时能产生贡献;当前这一位必须有偶数个人选 \(1\);后面的部分,可以发现其他人无论怎么选,一个当前位为 \(0\) 的人(无限制了)一定存在一个方案使得异或和为 \(0\)。
然后我想了个斯特林反演,假了,因为过程中会破坏异或和为 \(0\) 的条件。
咕。。。
T4
似乎是莫反,太难了没改。
8.19
T1
憨憨博弈,不用考虑什么 SG 函数,只考虑必胜 / 必败,DP。
T2
可以发现任何一种利用传送门的操作,一定可以化为从一个点作为中枢,走到离墙最近的方向的顶头传送到其它三个方向的顶头的操作。或者改为这样的操作不会变劣。
那么可以当作边跑最短路。
T3
Kruskal 重构树。建树的话从大到小枚举 \(\gcd\) 可以保证只在 \(\gcd\) 处连边。
T4
牛逼题。UOJ#211. 【UER #6】逃跑。
使劲容斥。
8.20
我不希望自己因为模拟赛频率变高而对此不认真。
T1
无向图欧拉回路计数似乎是不可做问题。考虑给所有边定向,然后套 BEST 定理。
可以发现给 \(v_0\) 确定了多少条边是什么方向,整张图就确定了方向。
BEST 定理将重边视为不同的边,所以每个定向的方案要除以重边的排列数。
T2
CF187D BRT Contract
查询某个时刻最早遇到的红灯,在 \(\bmod g+r\) 的意义下是区间覆盖、单点查询的问题。
T3
CF241B Friends
看错题了。二分然后算和可以俩 \(\log\)。
但是可以做到一只 \(\log\)!将 \(a\) 排序可以用区间代表子树,trie 树上逐层考虑。
T4
Luogu P4192 旅行规划
分块,块内维护凸包。
8.21
T1
一眼 wqs 二分。两层 wqs 二分然后归并是 \(\log^2\),赛时被卡常卡掉 10 分。减少一些内存不连续访问可卡过。
好像枚举两个人都喜欢的物品选多少个,剩下的就都确定了,我傻了。
T2
特判一下 \(0\) 的情况,剩下的就有单调性了,直接二分。
T3
把方程推到 \(x_0\),每次询问就是一个一元一次方程。
然后用数据结构维护树上单点修改、链和查询即可。
T4
一个矩形,四条边的每一条边,一定满足至少有一个点再边上(包括端点)。
考虑枚举左右边,在左边枚举点作为该边最上方的点,右边找到其下方纵坐标最接近的点,那么上下边就是两个区间内点对的贡献,树状数组维护个数和坐标和即可。
发现这是个枚举点对的过程,每个点与其配对的点是 \(\mathcal O(m)\) 的,复杂度 \(\mathcal O(nm\log m)\)。
8.22
又输了。
T1
分块。傻逼出题人让暴力过了。
T2
字符集 \(\mathcal O(n)\) 的 AC 自动机,用主席树建 trie 图就好。
这时候是无法用广义 SAM 代替 AC 自动机的,因为维护儿子集合的问题,复杂度是 \(\mathcal O(n\cdot |\Sigma|)\)。
T3
又是博弈。
由于获胜目标变为了最后一轮游戏胜利,所以可以有策略地让某一轮输掉或者胜利,状态变为了四种,是否有 win 的能力和是否有 lose 的能力。
建 trie 后 DP。
T4
UOJ#140
8.24
T1
考虑枚举 \(g=\gcd(a,b)\),那么 \(x=\frac ag,y=\frac bg\) 就都是完全平方数,可以做到 \(\mathcal O(\sum_{d|n}\sqrt{d})\)。
减少枚举 \(g\) 的数量。提出 \(g\) 所有完全平方因子 \(g=\alpha\beta^2\),然后枚举无完全平方因子的 \(\alpha\),那么甚至不需要要求 \(\beta^2x\) 和 \(\beta^2y\) 互质了。复杂度玄学。
T2
奇偶分类,两两配对,把 \(1\) 拿出来单独讨论。
二分图匹配尽量不匹配 \(1\),跑一次加点再跑一次即可。
T3
点分树上跑 bfs。
T4
点分树,每个连通块用线段树维护编号区间最小值。
8.25
T1
树形背包,记一个回去的和一个不回去的。
T2
按 \(k\) 分块。
T3
\(\min\{|a_i-a_j|\}\) 随 \(m\) 单调不增,二分两个函数的交点,用 std::multiset<> 维护距离不超过 \(m\) 的点对最小差,可以做到 \(\mathcal O(n\log^2 n)\)。
\(\mathcal O(n\log n)\) 其实是省去二分,直接双指针,根据两者的大小决定如何移动。
T4
两个边界都可以二分。
8.26
T1
倍增找这个 \(\mathrm{LCA}\),用树状数组求子树和可以 \(\log^2\)。
因为不需要求具体的子树和,在 dfs 序上用 std::set<> 找前驱后继的黑点,可以 \(\log\)。
T2
折半状压,拼接状态可以发现是二维偏序。
T3
别人的扩展域并查集做法看不懂……
首先可以转化为每条链将一些边并入同一集合,然后答案为 \(2^{\text{集合数}}\)。链并操作可以用并查集维护集合最高点然后暴力跳,复杂度是对的。
然后考虑无解的情况。无解情况一定是在某个路径两端点的 \(\mathrm{LCA}\) 处产生的。对于每个点 \(u\),其下方若干条边:在同一路径的边对,方向一定是一上一下;而其中与 \(u\) 上方边处于同一集合的边,一定方向相同。那么可以转化为二分图判定。
T4
矩形之间形成树形结构,同一颜色的所有射击产生的贡献是链的并。
考虑用 KDT 区间覆盖、单点查询,求出所有树边和射击起点,然后对于每个颜色建一个虚树算贡献。复杂度 \(\mathcal O(n\sqrt n)\)。
8.27
今天心情不好,就摸了。
T1
点数只有 \(9\),考虑用 Floyd 将最短路化为矩乘。
然后用个倍增或线段树求区间乘积。
T2
对于值域上已存在的区间 \([1,k]\),如果有加入数 \(k+1\),那么可以将区间扩展至 \([1,k+2]\)。
我们从小往大暴力找,扩展区间 \([1,k]\) 至找不到数 \(k+1\),那么就找到了 \(\mathrm{mex}\),次数规模 \(\mathcal O(\log 10^9)\)。用主席树来维护。
T3
先弄出 dfs 树,那么对于树边和反祖边分类讨论。
反祖边和只被这条边覆盖的树边可以成为合法边对;然后是未被覆盖的树边和反祖边。
剩下的我们只用关心树边。两个树边如果被覆盖的反祖边集合相同,那么删掉即不连通(两树边之间的部分若连出其它边,一定会导致其中一条树边再被另一条反祖边覆盖)。
那么给每个反祖边随机一个权值,然后给覆盖的树链异或上即可。
加强版结论:每次删掉 \(k\) 条边图不连通的充要条件为,这 \(k\) 条边权值不能全部成为同一组线性基的基底。因为不可能出现三条出边覆盖集合为 \(\{a,b\},\{b, c\},\{a,c\}\) 的情况,线性基能够帮我们找到相同的点对,并且消除已删除反祖边的影响。
T4
又是数位 DP。应该发现的性质是数字积不大,质因子只有 \(2,3,5,7\),大小在 \(\sqrt R\) 级别,并且可能的状态大约有 \(4e4\) 种。
递推一下 \(f(i,j,k)\) 表示 \(i\) 位首位为 \(j\) 数字积为 \(k\) 的数字个数,用 std::map 存一下。然后枚举数字积 \(x\),DP 求 \(((L-1)/x,R/x]\) 内数字积等于 \(x\) 的个数。
8.28
窝囊。
T1
暴力容斥。
T2
每个连通块里一定是有偶数个奇度点,考虑两两配对连边,并且余出两个用来于其它连通块相连,是最优的。注意没有奇度点的情况。
具体实现,可以把所有奇度点向虚点 \(0\) 连边,然后从 \(0\) 开始跑欧拉回路。
T3
点分树 + 线段树维护区间一次和、二次和,会 T 飞,满数据本机 12s。
考虑每条边的对答案增量的贡献,好好推式子可以直接线段树。
T4
考虑前 \(n\) 个字符的 DP,\(\mathrm{ans}\gets 2\mathrm{ans}+1-f_i\),那么在后面的 \(m\) 个空位中一定是每次选 \(f\) 最小的字符。
可以发现 \(\forall i < j, f_i< f_j\),因为 \(\mathrm{ans}\) 是单增的,所以用队列维护 \(f_i\),每次取队头就是最小值。然后将 DP 改成矩阵转移。

浙公网安备 33010602011771号