UOJ NOI Round 6
再次体验到了挂分的乐趣。。。
Day 0
按理来说应该是要参加 笔试 的,结果和同学踢球错过了报名。。。于是咕了。。。
队友极假,三颗单刀一颗没进,无脑致敬斯特林,体验极差。。
Day 1
T1 面基之路
首先注意到 hehe 是肯定不会走回头路的,因为所有人速度都相同,走回头路不如站在一个地方等其他人过来,所以最终一定是所有人都走到一个地方。所谓面基,就是走到某个约定好的地点罚站,等最后一个人过来。。。
于是对 \(k\) 个点中的每个点跑一次最段路,要求的就是点上或边上的一点使得所有人到这个点的最大距离最小,点上的很好求,边上的只要将这 \(k\) 个点排序或二分答案即可,不加以赘述。貌似只有我写了二分答案,常数大的离谱。。。
T2 机器人表演
与官方题解不同,这是取自评论区的一种做法。不知道为何被点了十几个踩。。。
首先这肯定是一个 \(dp\) ,于是考虑设计状态。不要看到括号就去想区间 \(dp\) ,因为给出的串 \(s\) 并不满足括号匹配。。。考虑是否存在一种方法将一个 \(01\) 序列 \(t\) 唯一的表示出来,不难想到先找出最长的 \(s\) 的前缀满足它是 \(t\) 的一个子序列,那么剩下的括号就是新加入的 \(t\) 对 \(01\) 。
于是设状态 \(f_{i, j, k}\) 表示 \(s\) 中最长能与 \(t\) 匹配的长度为 \(i\) ,剩下的序列中有 \(j\) 个 \(0\), \(k\) 个 \(1\) 的方案数,因为每个合法 \(01\) 序列可以被唯一表示,所以只要转移正确就一定不会出现被算重或少算的情况。
接下来考虑转移,先按照长度枚举所有的状态 \(f_{i, j, k}\) ,转移就是枚举下一个位置要添 \(0\) 还是 \(1\):
若要添的数其好等于 \(s_{i + 1}\) ,那么只能转移到 \(f_{i + 1, j, k}\) ;
否则对 \(0\) 和 \(1\) 分类讨论,若要添 \(0\) 显然是没有限制的,可以直接转移到 \(f_{i, j + 1, k}\) ;
若要添 \(1\) ,注意到为了满足括号匹配,只有在 \(j > k\) 的时候可以直接转移到 \(f_{i, j, k + 1}\) ;
否则无法直接转移,但并不代表这种情况一定不合法,注意到可能存在一个位置 \(pre_i\) 满足 \(s_{pre_i} = 0\) ,且 \(s_{pre_i + 1, i}\) 是合法括号序,那么将 \(s_{pre_i, i}\) 归类到新加入的括号,记这一段的长度为 \(len\) ,即可转移到状态 \(f_{pre_i - 1, j + \frac{len}{2} + 1, k + \frac{len}{2} + 1}\) 。
T3 稳健型选手
乍一看没有什么思路,于是先从暴力想起。
直接求最大的贡献很困难,于是正难则反,考虑算另一个人最小的贡献。注意到两人是轮流选取的,且我们考虑的这个人只选最左边的数,那么进行到第 \(2i\) 轮的时候,选了 \(i\) 个数,因此选择的第 \(i\) 个数,一定是在第 \(2i\) 轮之前,于是一种贪心的策略是每次加入两个数,选出此时还没选的最小的数,用堆维护即可,时间复杂度 \(O(nq \log n), 40pts\) 。
考虑另一种贪心,之前是从左向右枚举的,如果从右向左枚举可以吗?显然也是可以的,每次向左加入两个数,因为第 \(i\) 个数是在的 \(2i\) 轮之前选择的,所以新加入的两个数中,较小的那个必须选择,较大的数如果比已经选择的数中最大的小,就选择它(类似于反悔贪心)。这样便实现了同时向两边扩展,可以用两个堆,分别维护选择的数和为选择的数,用不删除莫队即可做到 \(O(n \sqrt(n) \log n), 70pts\) 。然而我写的太丑 TLE 了。。。只是徒增了罚时。。\kk
此时这个做法离正解已经很接近了,将上面两种贪心的规则规范化,就是对于前 \(2i\) 个数中,一定会选择 \(\ge i\) 个数,对于后 \(2i\) 个数中,一定选择 \(\le i\) 个数。不难通过看题解等方法想到可以用分治解决这个问题,对于每个询问,只在第一个它跨过分治中心的区间计算它,由上述贪心可得,对于分治中心的左边,有一些数是必须选的,而对于分治中心的右边,有一些数是一定不会选的,于是用两棵主席树,分别维护左边和右边可能选择的数,每次相当于在两棵主席数中求一个前 \(k\) 大的和。
然而这题被 \(Ring\) 用 \(O(n \sqrt{n} \log _w n)\) 水过去了,跑得还比我快。/kk
认清了自己人傻常数大的本质。。。
Day 2
T1 小火车
喜提最劣解。。。
注意到 \(p < 2^n\) ,乍一看是个很没用的条件,注意到每个一个大小为 \(n\) 的集合有且只有 \(2^n\) 个子集,那么至少存在两个集合的和在 \(mod \ p\) 意义下是相等的,只要找到这两个集合即可构造出答案了。直接求解两个集合较为困难,因此考虑求出这个集合的和是多少。
枚举所有的子集和显然不现实,因此尝试二分答案,注意到和在区间 \([l, r]\) 内的子集数量大于 \(r - l + 1\) 是区间 \([l, r]\) 内有解的必要条件,而若区间 \([l, r]\) 满足条件,则其子区间 \([l, mid], [mid + 1, r]\) 中也必然有一个满足条件,而区间 \([0, p - 1]\) 一定满足条件。现在只要能较快的求出一个区间内多少集合便可以二分了,注意到 \(n\) 只有 \(40\) ,可以 meet in the meddle ,枚举前 \(\frac{n}{2}\) 的集合,提前将后 \(\frac{n}{2}\) 的集合排好序,用三个指针分别维护 \(\ge p\) 的答案和 \(< p\) 的答案即可。
然而不知为何我的写法常数极大。。。
认清了自己人傻常数大的本质。。。
T2 神隐
首先有一个显然的二进制分组,就是对于二进制编号的每一位,另所有包含这一位的边和所有不包含这一位的边分别选一次,一共询问了 \(2 \log n\) 次,每条边都被选了恰好 \(log\) 次。然而这样询问次数太多了,考虑优化,注意到 \(\binom{20}{10} > n\) ,可以将每条边赋值一个 \(20\) 位,包含恰好 \(10\) 个 \(1\) 的二进制数,再类似于上面对于每一位,仅询问所有这一位有 \(1\) 边即可,这样对于 \(20\) 次询问,每条边被选了恰好 \(10\) 次。考虑到每条边被选了恰好 \(10\) 次,那么若有一对点 \(u, v\) 恰好有一半的询问满足这两个点在同一个连通块内,那么这两个点之间一定有一条边。
然而这样实现是 \(O(n^2)\) 的。。于是考虑用一种剥叶子的思想(貌似是交互中常见的思想。。),若一个点是叶子节点,也就是只有一条出边连向父亲,那这个点一定在恰好一半的询问中都是单独一个点作为一个连通块,便将其拨除,然后找到所有包含它的连通块中,看是否会出现新的叶子。对于找一个点的父亲,可以在其父亲被剥除时进行,父亲所在的某个连通块中,若所有点都被拨除,那其中所有还没有找到父亲的点一定都是它的儿子。
Border 的第五种求法
为什么这题有人场切啊。。。 \(DAG\) 剖分是什么鬼。。。
Summary
感觉分有点小低。。。如果不是今年名额多就打铁了。。。
于是大概分析了一下。。。
首先是没有参加笔试,大家去打 NOI 记得参加笔试哦。。。
\(Day \ 1\) 其实打得还行。。大概就是个大众分的水平,但是 \(t2\) 暴力分打的太少了,考场上想到了状态,但是不够自信也就没有深究,只写了最裸的暴力,实际上最裸的 \(dp\) 套 \(dp\) 都有不少分。。。 \(t3\) 的回滚莫队没有卡常,惨遭 \(TLE\) 也比较可惜。。。
\(Day \ 2\) 就挂的比较惨了,同样是常数问题, \(t1\) 挂掉了 \(20pts\) ,写 \(t3\) 的时候想起了一个不知道从哪看来的假结论,浪费了不少时间,也只得了暴力分, \(t2\) 的暴力写的太少了,貌似人均 \(50pts\) ,而且那个二进制分组的做法在之前的模拟赛中见过。。属实可惜。
烤场上不要奢求想正解,不要在一道题上浪费过多时间,每道题都应适当分配足够的时间,两天的暴力都没有打全,丢了不少分,属实可惜,希望国赛赛场上能发挥的好一点罢。。。
还没改完/kk