CSP-s 2019 江西重赛
A 日期
签到题,做法很多,我推荐最简单最保守的做法,就是枚举所有合法的日期,然后一个一个比较答案,最终答案取 min 值。
B 和积和
简单题,题目的形式已经很明显的表明了做法,推式子即可,下面是推式子的具体过程:
我们把其中一个 \(i \ (l \le i \le r)\) 单独拿出来,那么显然和 \(a_i\) 有关的式子可以提出来成为
对于每一个数 \(a_i\),跟他有关的 \(S(l,r)\) 是 所有 \(S(l, r)(l \le i \le r)\),简单推出对于每个 \(j\),贡献是 \(a_i \times b_j \times [j 出现的次数]\),这个东西很好推。
C 网格图
考虑直接 kruskal 做最小生成树,一次直接把一列或者一行的边全部加进去(能加进去的话),但是并查集显然不合适了,可以画画图看看怎么做(主要是看能加进去几条边),然后就没了。
D 散步
题意刚开始很难理解,但多读读就理解了,理解题意后思路就特别显然,但是代码写起来很不舒服。
即便如此,我的代码对比了题解的其他代码,还算简单。
对每一个出口单独考虑。可以用 set(一会儿解释为什么使用 set 而不是数组)的前驱后继找出如果没有其他出口的干扰,下一个到达这个出口的人的编号和到达时间。
把所有出口的这样的信息放到优先队列里面,目的是每次找出下一个出去的人信息和出口信息。
每出去一个人,就把他从 set 里面去除,以防别的出口再觊觎他。
这时需要注意,可能一个出口盯上的会从他这里出去的人。已经从别的地方出去了,这时直接标记一下每个人有没有走就可以了。
复杂度其实不好证明,讨论区也对这个解法的讨论度很高,但是我感性证明出来复杂度是对的,读者可以自行证明,总之是可以通过的。
E 多叉堆
根据两个操作,显然并查集。
简单计数,设 \(f_u\) 表示 \(u\) 对于询问 \(2\) 时的答案,同时要求 \(u\) 一定是所在树的根节点,因为我们并不查询非根节点的答案。当然,我们直接不维护那些非法的 \(f_u\) 就可以了,不必过多考虑。
先不思考如何把 \(v\) 连接到 \(u\) 下面,先思考一个树的答案是怎么通过 dp 求出答案的。
- 根节点显然是最小值。
- 根节点的所有儿子称作 \(v_1, v_2, v_3, \cdots, v_n\)。
- 每个儿子 \(v_i\) 都需要一些数填进去,同时他们自己又有自己子树的答案。
- 注意到每个儿子都是独立的。
现在,如果我们新加入一颗子树,无非是 \(n\) 加了 \(1\),同时多了一个乘数,可以很简单的更新 \(f_u\)。

浙公网安备 33010602011771号