do_while_true

一言(ヒトコト)

The 2022 ICPC Asia Nanjing Regional Contest

A

题解

先求出没有洞的话,最终留下来的袋鼠是哪个矩形。再看洞相对袋鼠是怎么移动的,这个洞会留下来一个移动轨迹。check 一个点是不是答案,就是看这个移动轨迹和袋鼠矩形的交的大小。那么每次是对移动轨迹进行一个二维数点。移动轨迹坐标必须在 \([-n,n]\)\([-m,m]\) 之间,要不然最终一只袋鼠都不剩可以直接特判掉。所以二维前缀和即可。

B

题解

求出 \(f_i\)\(g_i\) 分别代表考虑 \(i\) 作为断电的前缀 / 后缀,并且选了 \(i\),最小代价是多少。

答案可以用一个前缀和一个后缀拼起来,那就分为两种:选了 \(p\) 和不选 \(p\) 的。对于 \([p-k,p-1]\)\([p+1,p+k]\) 这两个区间:

  • 选了 \(p\):左边 \(f_{\min}\) 和右边 \(g_{\min}\) 再加 \(v\)
  • 没选 \(p\):左侧 \(i\) 和右侧 \(j\),并且 \(j-i\leq k\),求 \(\min\{f_i+g_j\}\)

前者直接扫一遍,后者搞个单调栈就行。

C

会不会补呢

D

题解

二分答案,\(\geq mid\) 的设成 1,\(<mid\) 的设成 0.那么第 \(k\)\(\geq mid\) 当且仅当可以让 \(1\) 的个数 \(\geq k\).每个数作为 1 的一定是一段区间,这样就能 \(\mathcal{O}(n)\) check 了。

E

题解

暴力是 \(f_{x,i}\)\(x\) 子树内距离 \(x\)\(i\) 的点全部变黑的代价是啥。\(f_x\) 首先是所有儿子的 \(f\) 加起来,位移一位,前面添个 \(a_0\),然后再对应位置和 \(a_i\)\(\min\)

上个长剖,每个位置再记录一个 tag,表示这个东西上次 chkmin 是对 \(a[?]\) chkmin 的就行。

这里这样做是因为长链往前添的时候,后面的不能动。但是这个 chkmin 并不急着求出来,当短链往长链上合并的时候再把短链上延迟的那些给更新掉就行。

由于要对 \(a\) 求区间 \(\min\),所以需要上 ST 表,复杂度是 \(\mathcal{O}(n\log n)\)

F

这题有点逆天。

G

题解

贪心,发现尽可能选 2 更优。那就能选 2 就选 2,选不了 2 再选 1.如果有一次强制 2 操作不了了,就把之前的一次选 2 反悔成选 1.

H

题解

看看 \(n^2\) dp:

\[f'_{u,t}=\max_{i+j=k}\{f_{u,i}+f_{v,j}+wj(k-j)\} \]

然后 slope trick,考虑差分数组的变化相当于整体加等差数列,或者把俩差分数组给归并起来。平衡树维护一下,支持打等差数列加的 tag,以及启发式合并。

启发式合并的时候 finger search(splay 自带)复杂度是 \(\mathcal{O}(n\log n)\)

I

签到。

J

题解

连边是咋连的?同一条斜率为 1(或 -1) 的直线上的点互相连边。对每个斜率为 1(或 -1) 的直线建个点,对于平面上每个点再把它所在的两个直线对应的点给连起来。

那么原先的完美匹配就是说要找到一个完美的边边匹配方案。这个就是经典问题,如果有连通分量里面如果是奇数条边就无解了,否则随便拉出来一个生成树,在上面自底向上贪心匹配即可。

K

题解

合法的一定是 NaN 的左右子树都是堆结构,然后 NaN 的子树补是个堆结构。

先考虑计数,\(f_{n,k}\) 表示大小为 \(n\) 的完全二叉树,子树中有个大小为 \(k\) 的 NaN 子树,概率是多少。

注意到本质不同的 \(n,k\) 只有 \(\mathcal{O}(\log n)\) 种,所以记忆化搜索一下就是对的。

学习一下 ymh 老师的写法!\(k\) 之间没啥关系,所以在外面枚举 \(k\),这样代码能简便很多。

L

题解

切掉的两条边都是非树边肯定不行。那就这三种情况:

  • 至少有一条是树边中的割边。
  • 一条是树边,另一条是覆盖这个树边的一条非树边,并且树边仅被这条非树边覆盖。
  • 都是树边,并且满足所有的非树边对着两条树边覆盖情况相同(都覆盖或者都不覆盖),为了避免计重还要保证这俩都不是割边。

第一种情况需要求割边数目,第二种情况是求有多少树边仅被一条非树边覆盖,线段树。

第三种情况:覆盖情况相同的边用双向链表连接起来,每次加边的时候会有若干个双向链表会进行分裂,而会分裂的一定是 \([L,R]\)\(pre_i<L\)\(nxt_i>R\) 的。由于最多分裂 \(n\) 次,那么线段树维护 pre 和 nxt,暴力递归切开就是对的。

还有一个问题就是要支持双向链表的分裂,以及记录每个双向链表的大小。采用启发式分裂,大的那边用原来链表的编号,size 就直接打个 tag;小的那边重构。

这样总的复杂度就是 \(\mathcal{O}(n\log n)\) 了。

M

题解 考虑让一个谷在最底下的平坡的最左侧的点被统计到,那么就要求前面是往上走的,后面是先平一段再往上走的。但是要区分内部和外部,注意到逆时针给定多边形,那么线段的左侧是多边形内部,分类讨论一下几种情况,判叉积就行了。

咋都判得比我简洁。

posted @ 2023-05-02 22:00  do_while_true  阅读(56)  评论(0编辑  收藏  举报