2020北大集训题解

能听懂的就尽力写吧。代码肯定是都咕了。

Day 1

T1

再次感谢出题人不杀之恩,给了我 89 分这个鬼畜分数。

做法(不是写法)和正解完全一样,然而还是不知道自己怎么错了。

心情好了再去看 https://uoj.ac/problem/427 。这题不仅被甩了 11 分还花了 3h ……

T2

真就联赛模拟题啊 /jk

获得成就:上台讲题。

先考虑一个区间怎么做。对于每个位置直接处理出 \(pre_i\) 表示往前第一个不被包含在它的子树内的位置,可以线段树二分求出。然后就是一个二维数点。

多个区间的话,相当于给这个区间加了一个额外限制,即必须是某个点 \(L\) 的祖先。同样先线段树二分,得到第一个满足该条件的点(然而写这句话的时候发现这好像不太好做,所以要线段树二分出这个区间的一个前缀,使得前缀的 \(lca\) (好像 \(lca\) 也不好搞,只能是关于 dfs 序的某些东西)是 \(L\) 的祖先。所以我场上写的线段树二分可能复杂度还是错的???)。此时,前缀的所有点都一定不满足条件,而对于后面的点,如果子树中能包含这个前缀,自然也就能包含 \(L\)

线段树上只维护 \(dfn,low\) 。复杂度 \(O((m+Q)\log m)\)

T3

挺有趣的一道题,可惜场上没时间想。

称 x-度点 表示有 \(x\) 个儿子的点。

subtask 1

在这档部分分中,树中不存在一度点。

容易发现询问 \(V\backslash\{x\}\) 可以得到这个点是否是叶子,那么先用 \(n\) 次操作得到此时的叶子集合。然后考虑怎么确定叶子的父亲,发现当 \(x\) 是叶子时可以询问 \(V\backslash \{x,y\}\) 来确定 \(y\) 是否是 \(x\) 的父亲。如果 \(fa_x=y\) 那么会返回 \(n-2\) ,否则是 \(n-1\)

然后发现这个枚举 \(y\) 的过程其实可以直接二分一个前缀,就可以在 \(O(\log n)\) 的时间内得到一个叶子的父亲。发现两个叶子的父亲相同之后就可以删掉这两个叶子,并把它们的父亲加入叶子集合。

这样就获得了一个 \(O(n\log n)\) 次询问得到树形态的做法。

subtask 2

此时树中可能存在一度点,但询问次数更多(当然数量级没有变)。

考虑上面的做法,会发现在第一步就直接错了:询问 \(V\backslash \{x\}\) 并不能区分零度点和一度点。我们先把二度点区分出来,然后考虑零度点和一度点的集合 \(S\) 。那么询问 \(S\backslash \{x\}\) 会有两种取值:

  • \(n-2\) :这个点是零度点,且它的父亲是一度点。
  • \(n-1\) :这个点是一度点,或者它是零度点且它的父亲是一度点。

容易发现如果出现 \(n-1\) 的第二种情况,那么一定无法确定树的形态。所以先不考虑这一种情况,求出三种点的数量 \(c_0,c_1,c_2\) 。由于真正的 \(c_0\) 应当等于 \(c_2-1\) ,所以如果不满足这个条件就直接返回无法确定。

然后用 subtask 1 的做法先得到只考虑零度点和二度点的树形态,然后尝试把一度点塞进去。

然后又是一个性质:在二叉树中,询问一个点集,可以根据大小来判断是否至少有一组 祖先-后代 关系。那么选择一个叶子集合 \(L_0\) 和一个一度点 \(x\) ,询问 \(L_0\cup \{x\}\) 即可确定 \(x\) 的子树中是否存在 \(L_0\) 中的叶子。如果总叶子集合是 \(L\) ,那么询问 \((L\backslash L_0)\cup\{x\}\) 就可以知道 \(x\) 子树的叶子集合是否被 \(L\) 完全包含。

现在树的基本形态已经确定了,所以可以边分治,确定所有一度点是在这个子树内,在外面,还是恰好在这条边上。

出题人用神奇分析方法得到了询问次数上界是 10408 ,不太懂怎么做到的。

Day 2

T1

签到题。

明天 危 ……

T2

算法一

神奇维护分段函数,这竟然还能维护出来 /jk

算法二

显然应该旋转 45° ,使得横纵坐标互相独立。

然后再稍微搞搞就得到了: \(2n\) 个随机变量,每个变量取值 \([-{1\over 2},{1\over 2}]\) ,求 \(|\sum x_i|\) 的期望。

然后掉线了。

算法三

wdnmd 为什么这还和算法二有关……

也掉线了。

算法四

场上做法。我也不知道为什么它是对的,但它就是对的。

\(n:= 2n\)

\(s_0=0,s_i=\sum_{k\le i} x_k\) ,那么答案是 \(|s_n|\) ,有限制 \(s_i\in [s_{i-1}-{1\over 2},s_{i-1}+{1\over 2}]\)

先把 \(|s_n|\) 变成 \(\max(s_n,0)\) ,然后类似 \(m=\sum_{i=0}^{\infty} [i<m]\) ,再变成 \(\int_0^{\infty} [s_{n+1}<s_n]\text{d}s_{n+1}\) (大概不能这么写,但我不知道怎么写)。

限制有点麻烦,但是可以容斥变成 \((-\infty,s_{i-1}+{1\over 2}]-(-\infty,s_{i-1}-{1\over 2}]\) (用离散的方案数的角度很好感性理解,但是它是连续的,所以我也不知道为什么是对的)。那么就变成一堆 \(s_i\le s_{i-1}+k\) 的限制,以及一个 \(s_{n+1}\ge 0\)

这个形式就非常好看,对于 \(s_i\le s_{i-1}+k\) 可以给所有 \(j\ge i\) ,做 \(s_j:=s_j-k\) ,那么做完之后就只剩下 \(s_i\le s_{i-1}\)\(s_{n+1}\ge c\) 了,其中 \(c\) 是前面所有 \(k\) 加(减?)在一起。

容斥显然可以变成 \(O(n)\) 枚举,就得到了答案式子:

\[{2^{-n-1}\over (n+1)!}\sum_{i=0}^{n} [2i-n\ge 0] (2i-n)^{n+1}{n\choose i}(-1)^{n-i} \]

(可能有一些正负写错了,记不清楚了)

(这里的 \(n\) 仍然是输入的 \(n\) 的两倍)

然后由于未知原因要特判 \(n=2\) ,就做完了。

T3

算法一

kosaraju 是个啥?

算法二

每个强连通分量分别做,找到一条哈密顿回路,那么翻转不在回路上的边答案不变。

然后神奇方法冲。

算法三

wdnmd 我怎么又掉线了……

然后标算被踩了 /cy

有一个经典结论:只看出度序列就可以直接得到强连通情况。

然后翻转一条边只会修改两个位置,就做完了。

标算和哈密顿回路有关,大概是(?)先找一个哈密顿回路出来,那么其他边修改都是无效的,而翻转回路上的边会把回路变成链,其他边会覆盖一个区间,然后乱搞搞。

Day 3

T1

直接行列式,做完了。

被打爆了 /kk

T2

合法当且仅当每个位置开头的逆序对个数都是偶数。

然后 \(O(n^2)\) 有手就行。

剩下的事交给 lxl 。

想到分块,每个块建线段树,然后无脑暴力,即可做到 \(O(n\sqrt {n\log n})\)

然而线段树的常数炸了。

我们其实只关心一个块内有没有 1 ,所以可以把线段树变成差分。虽然还是要二分查 rank ,但是常数明显降低,就过了。

好像还有 \(O(n\sqrt n)\) 做法但是让卡常的人都见 lxl 去吧

T3

wdnmd 还真是 lxl ……

穿着 DS 外衣的模拟题?不想思考了。

Day 4

T1

\(O(n^22^n)\) 求出每个点集组成一条链的方案数,然后 \(O(n^22^n)\) 做子集卷积意义下的 exp 即可。

询问都是假的。

然后发现有不用 exp 的做法,被教育了。

还有直接冲 \(O(3^n)\) 也有一定概率通过。

T2

先建一个虚点,所有点向它连边,然后就等价于求一个内向生成森林个数。

不会矩阵树定理的已经被区分掉了。

然后发现矩阵是一个循环矩阵,求行列式有快速解法。然而我不会。

T3

subtask 1,2

直接完全 \(k\) 分图即可。

subtask 3,4,5

条件是不存在正方形,即任意两个点的邻居的交的大小不超过 1 。

对于一个点 \(x\) ,任取两个邻居 \(a,b\) ,令 \(cnt_{a,b}\gets^+ 1\) 。那么最终任意一个点对的 \(cnt\) 都不能超过 1 。由于只有 \({n\choose 2}\) 个点对,而一个点 \(x\) 贡献的 \(cnt\) 就有 \({deg\choose 2}\) 个,所以大概能估出 \(M\) 的上界是 \(O(N\sqrt N)\) 级别。

然后直接造一个 \(P\times P\) 的矩阵, \((u,v),(x,y)\) 有边当且仅当 \((ux+vy)=1\pmod P\) 。相当于是每个点连了一条直线,那么两条直线要么无交,要么交为 1 。

subtask 6

\((u,v,w),(x,y,z)\) 有边,当且仅当 \((u-x)^2+(v-y)^2+(w-z)^2=1\pmod P\)

wtf?

感性理解一下,就是向旁边一个单位球连边,然后操作一下就发现三个球的交不会超过两个点。

posted @ 2020-12-08 19:46  p_b_p_b  阅读(751)  评论(0编辑  收藏  举报