2025/8/7胡题记录
最近忙着背科目一和学范畴论,根本没时间加训
CodeForces - 1439C. Greedy Shopping
刚看到题就想了很久但是不会做,然后发现自己没有注意到序列 \(\set{a_i}\) 是单调不增的。首先先考虑问题的弱化形式——没有修改的情况,实际上印象里以前并没有见过比较典型的能处理这类问题的模型,于是尝试分析购物情况,能够发现购买的商品一定是一段一段的,显然这是废话,但是不难发现一个情况:假如一段连续的购买是 \(a_l\) 到 \(a_r\) 这就意味着这个人是买不起 \(a_{r+1}\) 的,即 \(money<a_{r+1}\),那么尝试分析下一次购买 \(a_x\) 是怎么样的,如果 \(a_x>{a_{r+1}\over2}\),那么钱就会直接减少一半,再下一次的购买 \(a_y\) 一定是 \(a_y\le a_{r+1}-a_x<{a_{r+1}\over2}\),而如果 \(a_x<{a_{r+1}\over2}\) 那么就直接说明下一次购买变成了原来的一半,这意味着购买的商品的段数一定是 \(O(\log V)\) 级别的,于是就直接在线段树上二分即可,感觉困难的地方应该在于发现这一个性质,有一点点欧几里得辗转相除法的味道。
CodeForces - 1706E. Qpwoeirut and Vertices
求最小的边使得图联通,一闻就是最小生成树的味道,实际上就是在最小生成树模拟,一旦最小生成树的过程中某个要求被满足了就回答当前处理的边即可,实现方法应该有很多种,比如重构树或者整体二分。
CodeForces - 1712E2. LCM Sum (hard version)
这个题目乱七八糟的,感觉就是纯乱搞+大力分类讨论。首先容易分析出 \(k|lcm(i,j,k)\),并且如果 \(k<lcm(i,j,k)\) 则 \(2k\le lcm(i,j,k)\),所以实际上能够做到 \(lcm(i,j,k)<i+j+k\) 的情形是很少的,只能允许 \(lcm(i,j,k)=k\) 或者 \(lcm(i,j,k)=2k\) 且 \(i+j>k\)。
对于第一种情况,设 \(f(a,b):=\sum_x [x\ge b]\&[x|a]\) ,则第一类就是想办法维护 \(\sum_{l\le x\le r}f(x,l)^2\) 和 \(\sum_{l\le x\le r}f(x,l)\)。考虑对所有询问按照 \(r\) 从小到大的顺序来扫描线,对于一个固定了的 \(a\) 而言,\(f(a,\cdot)\) 至多有 \(\sigma(a)\) 个不同的值,并且这些值是构成连续的段的,故全体的 \(f(\cdot,\cdot)\) 共有 \(\sum\sigma(i)=O(V\log V)\) 段不同的值,所以每次新加入一个 \(r\) 的时候把 \(f(r,\cdot)\) 对于 \(\sum f^2\) 和 \(\sum f\) 的修改打到线段树上即可,所以这一部分总的时间复杂度为 \(O(V\log^2 V)\)。
第二种情况和第一种情况类似,对于每个 \(i\) ,直接枚举 \(2i\) 的因子对,然后以同样的思路可以发现 \(g(a:b)=\sum_{(x,y)} [x,y\ge b]\& [lcm(x,y,a)=2a]\) 也是 \(\sigma(a)\) 段不同的值,然后全部拍到线段树上即可,时间复杂度为 \(O(\sum \sigma^2(i)+V\log^2V)\)
QOJ - 7661. Japanese Lottery
精妙的数学题,之前见过,但是当时苦于找不到合适的数学工具来描述交换的行为,前几天群中有人提及置换故而恍然大悟,故可从置换合成的角度来描述这一题目的行为。
题面:称二元置换为交换,对交换列 \(\set{\sigma_i}\) ,进行总共 \(q\) 次操作,每次操作形如在该列中某个位置插入一个交换或者移除某个交换,对于操作完后的长度为 \(m'\) 的交换列 \(\set{\sigma'_i}\) ,求最长的递增序列 \(\set{a_i}:1\le a_1<a_2<...<a_n\le m'\) 的长度 \(n\) 使得 \(\sigma=\sigma_{a_1}\circ\sigma_{a_2}\circ\sigma_{a_3}\circ...\circ\sigma_{a_n}=I\)
先说明上述问题的结论:设 \(\sigma\) 中有 \(s\) 个环,那么至少需要移除 \(|\sigma|-s\) 个置换,并且这个值可以取到。
一波三折,经过一周时间结论得到了证明,但是这个证明很复杂,我要新开一篇文章来写这个。
QOJ - 11503. Giant Gorilla’s Gift
势能线段树,以后看见奇奇怪怪的操作就尽量直接想暴力并利用势能分析法来证明复杂度。首先直接分析出至多有 \(7\) 个本质不同的质数,然后直接维护 \(8\) 个值即可,但是困难的地方在于第三种操作,但是实际上直接就是在线段树上二分找到下一个最近的能被修改的值,这是因为一旦有修改那么一个值至少被乘以二,而由于题目保证每个数时时刻刻都小于 \(10^6\) 所以实际上每个数能够被修改的总次数是 \(O(n\log V)\) 的,于是定义线段树的总势能为每个数能被乘以二的次数,显然一次操作二至多使得总势能增加 \(\log V\) 而操作三中的每一次暴力操作都会使得总势能至少减少 \(1\) ,故时间复杂度就是 \(O(n\log V\log n)\)
QOJ - 11509. Minor Maze Modifications
又是这种乱七八糟的题,不过幸好是计数题。感觉题目的核心就是处理出想要把两个联通块打通需要多少步,以及有多少种方案,但是就是乱七八糟的。时间复杂度应该是在 \(O(n^2)\) 级别的
QOJ - 11501. Eirt Eht Esrever
字符串题,注意到实际上在 Trie 树上的每个节点都代表一个字符串,这样的字符创要么是一个前缀,要么是一个子串的反转,而显然 Trie 树的节点个数的期望可以转化为每个节点出现的概率之和,由于需要分析子串,所以考虑在字符串上建立 sam,而一个节点作为子串出现的概率就可以直接通过 fail 树来计算,但是此时仅考虑了子串而未考虑前缀的情况,这个时候假设字符串为 \(S\) 那么考虑把后缀自动机建立在串 \(S+'\#'+reverse(S)\) 上,之后再在树上操作一下即可,时间复杂度是 \(O(n)\) 的.
QOJ - 11504. Hidden Hierarchy Hints
有意思的交互题,需要一定的注意力。
首先需要注意到一个结论:对于两个节点 \(x,y\) 而言,如果一个边 \(e\) 不在 \(x\) 到 \(y\) 的最短路径上,那么 \(e\) 相对于 \(x\) 的方向和相对于 \(y\) 的方向是相同的,若反之则方向是反的.
干脆钦定 \(1\) 为树的根,然后先问一遍 \(000...00\) ,之后对于每个边都反一下,即问 \(100...00,010..00,...,000..10,000...01\) ,规定边指向 \(1\) 即为正方向,从而得到每个边的方向,之后假定零一串 \(s:=0011010...010\) 代表了使得每个边都正方向的东西,则对于每个节点 \(i\) 询问 \(i\,\,\,s\) 从而得到每个节点的深度。至此已经询问了 \(500+499=999\) 次。(称求出来的 \(s\) 为标准状态,以后的操作都在标准状态上操作)
之后依照深度从小到大的顺序依次通过询问获取每个节点的以下信息:父节点、连向父节点的边.
首先对于深度为一的点 \(i\) ,已经知道父节点肯定是 \(1\) ,所以只需询问出哪个边是连向父节点的,不难发现:如果一个边不是 \(i\) 连向 \(1\) 的,那么翻转这个边会使得对于 \(i\) 的询问减一,否则加一。推广它,就是假设翻转了 \(k\) 个边,那么如果对于 \(i\) 的询问的值不等于 \(i\) 的深度减 \(k\) ,那么这个 \(i\) 连向 \(1\) 的边必在这 \(k\) 个边中,于是这提供了一种非常自然的二分的思路,这一思路本质上就是在询问哪个边在 \(i\) 到 \(1\) 的路径上。
而对于深度不为一的节点 \(i\),并不知道父节点是谁,于是还需要询问父节点是谁,具体的做法是:假定现在正在处理深度为 \(x\) 的节点,那么这意味着所有深度小于 \(x\) 的节点已经获取了他们全部的父节点、边编号信息了,于是将全体深度为 \(x-1\) 的节点的边给抽出来,用上面相似的思路,可以问出 \(i\) 的父节点的边,从而知道父节点的是谁。
之后处理边编号,还是一样的思路,只不过不要再询问已经确定了的边了。
上述的做法需要询问 \(2n(1+\log n)\leq 10000\),是一种可行的交互策略

浙公网安备 33010602011771号