9 月做题记录

学习一下 KTT,很牛啊。

已知有 \(n\) 个一次函数 \(k_ix+b_i\),有 \(m\) 个询问,每次询问 \(\max_{i=1}^n \{k_ix_j+b_i\}\)

做法其实很多,比如整体二分,李超线段树啥的。

\(n\) 个函数,随着 \(x_i\) 的增大,观察函数相对大小的变化,发现最多会变化 \(O(n^2)\) 次,难以直接维护。

注意到建成一颗线段树的形式,将一堆函数分成两半,如果左边右边都已经有序,那么中间相对位置的改变只会有 \(O(n\log n)\) 次,也就是和归并排序一样。

具体来说,因为要找最大值,维护左右两个区间里面当前最大的那个函数,然后随着 \(x_i\) 的修改如果左右最大的函数的大小关系发生变化就暴力修改。

为什么只需要取最大值呢,因为子区间里面如果有一个函数变成最大,就会先变成这个子区间里面的最大值,这个可以通过不断 push up 维护。

这样只需要记录左右子区间,小的那个还需要加多少才能超过大的那个,然后超过了就暴力递归修改,总共修改 \(O(n\log n)\) 次,总复杂度 \(O(n\log^2 n)\)

如果只是这里显然没啥用,注意到这个的厉害之处在于可以修改,可以支持对一个函数的单点修改,这是李超线段树做不了的,修改之后一样上传,复杂度应该还是 \(O(\log^2 n)\) ???


CF1823F \(\color{green}\bigstar\) *2600

发现一个 link,对着做一段时间。

简单题,设 \(f_{i,j}\) 表示 \(i\) 出发,到 \(j\) 的期望次数。

但是这样很混乱,因为一直随机游走,连设方程都不方便。

和树上随机游走类似,把行走过程划分成一个个阶段。

假设 \(s\to t\) 的路径是 \(a_1\to a_2 \to ... a_k\),那么划分成 \(k\) 个部分,每个部分向父亲走一步就进入下一个阶段。

那么状态变成 \(f_{i,j}\) 表示 \(j\in \text{subtree}(i)\)\(i\) 走到 \(fa_i\) 之前经过 \(j\) 的次数。

分析一下简单情况, \(f_{i,i}\),每次到 \(i\),有 \(\dfrac{1}{d_i}\) 的概率向上,否则进入子树,进入子树后肯定又会回到 \(i\),因此 \(f_{i,i}=d_i\)

分析一下 \(f_{i,j}(j\in \text{son}(i))\),得到 \(f_{i,j}=\frac{f_{i,i}}{d_i}f_{j,j}=d_j\),归纳一下发现 \(f_{i,j}(j\in \text{subtree}(i))=d_j\)

所以答案只要算一下一个点父亲有多少个在 \(s\to t\) 的路径上,答案就是 \(d_i\times f_i\),时间复杂度 \(O(n)\)

其实是可以带修的,瞎胡一下可以支持删点加点,查询 \(\{s,t,x\}\)

CF1830F *3200 \(\color{Gold}\bigstar\)

发现一个点的贡献只和右边第一个选的点有关。

\(f_i\) 表示 \(i\) 选了,\(i\) 前面点的总贡献最大值。

\[f_i=\max f_j+p_j*w(i,j) \]

\(w(i,j)\) 表示包含 \(i\),不包含 \(j\) 的区间个数,那么这个扫描线后相当于只有区间加。

因此直接 KTT 维护区间加 \(p_j\) 即可。

CF1517F *3200 \(\color{blue}\bigstar\)

最大半径就是离他最近的 \(0\)

如果直接设 \(f_{i,j}\) 表示 \(i\),半径是 \(j\) 比较困难,因为上面也要满足,而且子树里可能有更大的。

枚举一个 \(r\) 求半径 \(\ge r\) 的方案数,这样变成判定性问题。

\(f_{i,j,k}\) 表示 \(i\) 子树内,最深的目前满足条件的点深度为 \(j\),离 \(i\) 最近的 \(0\) 距离为 \(j\),合并是树上背包合并,复杂度 \(O(n^5)\),爆炸,前缀和优化后是 \(O(n^4)\)

注意到,如果存在一个 \(j\),那么此时 \(k\) 是无意义的,因为必然不会影响其他子树,因为 \(j+k>r\)

所以两维不会同时有用,直接记录两个 \(f_{i,j},g_{i,j}\),树上背包合并 \(O(n^3)\)

loj2494 \(\color{Gold}\bigstar\)

非常好题目,赞美 HNOI。

一开始想了一个做法,就是从后向前,那么当前要求前缀一些位随意,一些位必须是 \(0/1\),然后就可以从后向前推,注意到出了最后一次,前面要求必须的位要么全是 \(0\),要么全是 \(1\),因此可以 bitset,复杂度 \(O(\frac{Qnm}{w})\),不知道能不能过。

对于每一位,把 \(1\) 放前面,\(0\) 放后面,那么当前有要求的一定是个区间。

考虑对于一位具体是咋搞的,如果最后是 \(1\),然后填或就直接是 \(1\),否则就无影响,相当于一个二进制的比较。

因此做法就简单了,排序一下,然后答案就是相邻两个二进制相减。

loj2495 \(\color{Gold}\bigstar\)

小丑题。

答案显然就是

\[\min \{\max_{j=1}^n a_{i+j}\}+i+n-1 \]

一开始想了个分块做法,不知道能不能过。

事实上这个东西只和后缀最大值有关,直接楼房重建就行。

loj2496 \(\color{green}\bigstar\)

非树边拉出来容斥,然后求一个独立集个数。

可以动态 dp,但是那样 \(m-n\) 可以开更大,这题正解是比较好写的虚树,只要维护每条链的系数就行。

posted @ 2023-09-12 21:16  houzhiyuan  阅读(24)  评论(0编辑  收藏  举报