能听懂的就尽力写吧。代码肯定是都咕了。
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)\) 枚举,就得到了答案式子:
(可能有一些正负写错了,记不清楚了)
(这里的 \(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?
感性理解一下,就是向旁边一个单位球连边,然后操作一下就发现三个球的交不会超过两个点。