做题

P4159 [SCOI2009] 迷路

矩阵快速幂优化递推。

首先最暴力的想法,设 $ f_{i,j} $ 在 $ j $ 时刻,到达点 $ i $ 的种类数。

枚举时间和 $ i $,然后 $ f_{i,j} = \sum\limits_{k=1}^n {f_{k,j-w[i][k]}} $。

时间很大,所以肯定行不通。

这样显然是不能用矩阵来优化的。

考虑拆点,每个点拆成九个点,对于一条边 $ u,v,w $,从 $ f_{u,0} $ 向 $ f_{v,w} $ 连一条边权为 1 的边,然后对于每个点,从 $ f_{u,i} $ 向 $ f_{u,i-1} $ 连一条边。

然后矩阵快速幂即可。

CF446C DZY Loves Fibonacci Numbers

分块板子题,区间加斐波那契数列。

其实和区间加等差数列差不多,每个块维护块头的 $ f_1 $ 和 $ f_2 $。

查询的时候直接下传递推即可。

P3265 [JLOI2015] 装备购买

实数线性基板子题。

AT_abc223_h [ABC223H] Xor Query

区间线性基。

有一个显然的做法是线段树上维护线性基,但是是 $ O(n\log^3n) $ 的,我不想卡常,所以没写。

考虑一点智慧的做法,给线性基做一个前缀和。

第 $ i $ 个线性基表示前 $ i $ 个数组成的线性基,并且记录一下这个位置是原序列上的哪个数。

由于我们到时候要删掉 $ [1,l-1] $ 的数,所以每一次插入的时候贪心的保留后面的。

查询的时候把记录的 $ idx \le l-1 $ 的数删掉就好了。

P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III

并非题单内的题,但是突然看到了就写一下吧。

预处理第 $ i $ 个块的众数,前 $ i $ 个块中 \(j\) 出现了多少次。

查询的时候答案只可能是散块内出现的数和整块众数,这个量级是 $ \sqrt{n} $ 的。

暴力枚举个数统计答案即可。

woc 怎么要卡空间?

对每个数开个 vector,然后预处理出 $ [l,r] $ 块的答案。

拿着答案的个数对着左边散块扫,扫到合法的就把答案向后推。

P4458 [BJOI2018] 链上二次求和

简单推式子题 并非简单。

简单推下式子,记 $ S_n = \sum\limits_{i=1}^n a_i ,SS_n = \sum\limits_{i=1}^n S_i ,SSS_n = \sum\limits_{i=1}^n SS_i $:

$ \sum\limits_{len=l}^r \sum\limits_{i=len}^n \sum\limits_{j=i-len+1}^i a_j$

$ = \sum\limits_{len=l}^r \sum\limits_{i=len}^n S_i - S_{i-len} $

$ = \sum\limits_{len=l}^r (\sum\limits_{i=len}^n S_i - \sum\limits_{i=0}^{n-len} S_i) $

$ = \sum\limits_{len=l}^r {SS_n - SS_{len-1} - SS_{n-len}} $

$ = \sum\limits_{len=l}^r {SS_n} - \sum\limits_{len=l-1}^{r-1} SS_{len} - \sum\limits_{len=n-r}^{n-l} SS_{len} $

$ = (r-l+1) {SS_n} - SSS_{r-1} + SSS_{l-2} - SSS_{n-l} + SSS_{n-r-1} $

然后维护 $ SS,SSS $ 就可以了。

再记 $ sum_0(n) = \sum\limits_{i=1}^n a_i,sum_1(n) = \sum\limits_{i=1}^n a_i \times i , sum_2(n) = \sum\limits_{i=1}^n a_i \times i^2 $。

那么 $ SS_n = \sum\limits_{i=1}^n \sum\limits_{j=1}^i a_j = \sum\limits_{j=1}^n a_j \times (n-j+1) = (n+1) \times sum_0(n) - sum_1(n) $。

$ SSS_n = \sum\limits_{i=1}^n \sum\limits_{j=1}^i \sum\limits_{k=1}^j a_k = \sum\limits_{i=1}^n \sum\limits_{j=1}^i a_j \times (i+1-j) $

$ = \sum\limits_{j=1}^n a_j \sum\limits_{i=j}^n (i+1-j) $

$ = \sum\limits_{j=1}^n a_j \sum\limits_{i=1}^{n-j+1} i $

$ = \sum\limits_{j=1}^n a_j \times \dfrac{(n-j+1)(n-j+2)}{2} $

$ = \dfrac{1}{2} \sum\limits_{i=1}^n a_i \times (i^2 - (2n+3)i + (n+1)(n+2)) $

$ = \dfrac{1}{2} (sum_2(n) - (2n+3) sum_1(n) + sum_0(n) (n+1)(n+2)) $

那么在线段树上维护 $ sum_0,sum_1,sum_2 $ 就可以了。

P4389 付公主的背包

前面忘了,中间忘了,后面忘了,反正这题要多项式。

把每个体积的生成函数的封闭形式乘起来,得到 $ res = \prod\limits_{i=1}^n \dfrac{1}{1 - x^{a_i}} $。

后面好像两边 $ \ln $ 再 $ \exp $ 之后就可以了,但是我不会,数学功底不够,后面再来补。

CF995F Cowmpany Cowmpensation

非常牛的一道 DP 题。

首先有一个很显然的树形 DP。

设 $ f_{u,i} $ 为节点 $ u $ 及儿子权值不超过 $ i $ 的方案数。

转移方程为 $ f_{u,i} = \prod\limits_{v \in son_u} f_{v,i} $ 。

这样转移就是 $ O(nd) $ 了,无法接受。

记子树大小为 $ siz_u $,那么 $ f(u,x) $ 为关于 $ x $ 的 $ siz_u $ 次函数。

证明我不会。

反正 $ d $ 的上界缩减到了 $ n $,时间复杂度 $ O(n^2) $。

最后用拉格朗日插值算一下答案就好了。

AT_yahoo_procon2019_qual_e Odd Subrectangles

01 矩阵权值和为奇数等价于异或和为 1。

假定现在已经选出了要选哪些行,那么我们挑一列异或和为 1 的出来,若其它列的异或和为 0,那就选这一列,若其它列的异或和为 1,就不选这一列。这样一共有 $ 2^{m-1} $ 种方案。

但要是选一些行出来它们的异或和为 0 就无法挑选出一列异或和为 1 的了,所以要减去异或和为 0 的子集的方案数。

考虑线性基,把每行看成一个数插入线性基,记线性记的大小为 $ siz $,那么根据线性基的性质异或和为 0 的方案数就有 $ 2^{n-siz} $ 种。

那么总方案数即为 $ 2^{m-1} \times (2^n - 2^{n-siz}) $。

P11364 [NOIP2024] 树上查询

也不是题单内的题,但是惦记这题好久了,也该写一下了。

非常套路的,计算出每一个 $ LCA $ 的支配对,每个支配对形如 $ [L,R,LCA] $。

然后可以转化为三维数点,记询问区间为 $ [l,r,k] $,分为三种相交的情况讨论:左边相交,右边相交,包含。

\[R-l+1 \ge k \]

\[r-L+1 \ge k \]

\[R-L+1 \ge k \]

然后对答案的贡献就是 $ dep_{LCA} $。

时间复杂度 $ O(n \log^2 n) $ 的。

P8082 [COCI 2011/2012 #4] KEKS

很显然的思路肯定是要把大的放在前面。

那我们肯定是考虑第 \(i\) 位,把它前面的小于它的都删掉。

用单调栈维护即可。

P8898 [USACO22DEC] Feeding the Cows B

从左往右扫,考虑记录一个 $ maxh $ 和一个 $ maxg $,表示这两种牛能够到达的最远的地方。

然后每一次超出最大的范围了,就从 $ i+m $ 向前找第一个可以放的位置。

从后先前找是因为要最大的满足后面的。

P6243 [USACO06OPEN] The Milk Queue G

若 1 奶牛比 2 奶牛更优:

\(a_1 + \max(b_1,a_2) + b_2 < a_2 + \max(b_2,a_1) + b_1\)

\(\max(a,b) = a + b - \min(a,b)\),则有

\(a_1 + b_1 + a_2 + b_2 - \min(b_1,a_2) < a_1 + a_2 + b_1 + b_2 - \min(b_2,a_1)\)

\(\min(b_1,a_2) > \min(b_2,a_1)\)

然后依据这个来排序即可,但是不可以直接丢到 $ sort $ 的那个比较函数里面,因为不满足传递性。

所以考虑另外一种排序方法,当 $ A<B $ 时,按 $ A $ 从小到大排序,当 $ A \ge B $ 按 $ B $ 从大到小排序。

P2255 [USACO14JAN] Recording the Moolympics S

以前感觉做过一个这种题,反正看上去就是用右端点排序,然后能填就填。

P2945 [USACO09MAR] Sand Castle S

直觉告诉我两个分别排一遍,然后直接算是对的。

CF3D Least Cost Bracket Sequence

神仙!!!

首先你先考虑把所有的 '?' 全部变成 ')'

从前往后匹配,当你的右括号多了的时候就想办法从前面找一个 '?' 来变成左括号

贪心的找,考虑把前面每一个问号的位置用优先队列存下来,然后里面的排序就用左括号的贡献减去右括号的贡献

这个就是右括号变成左括号的差值,你要让这个东西最小,贪心的选即可。

CF525D Arthur and Walls

不知道为什么是蓝题???

你直接扫一遍,碰到一个 $ * $ 就判断一下不是不被三个 $ . $ 夹着的,如果是就直接把它变成 $ . $,然后更新一下周围的就可以了。

P8896 「DPOI-1」道路规划

你发现这个东西的是一个竞赛图的 DAG

那么竞赛图的 DAG 的出度序列肯定是一个排列,证明如下

首先肯定有且仅有一个入度为 0 的点,否则就不满足是竞赛图或 DAG 了。

然后删掉之后还有且仅有一个入度为 0 的点,这个和上面同理。

所以这个东西的拓扑出度就是一个排列。

那么原问题就转化为重排一个排列,问是否可以满足对于每个 $ a_i $ 都有 $ l_i \le a_i \le r_i $。

这个贪心就可以了。

CF1208G Polygons

这个东西也非常牛!!!

首先假设你现在已经选了 $ n $ 边形,那么你就可以选它所有的因数了,因为选它的因数这个是不会增加新的贡献的。

所以说一个数的贡献其实就是 $ \varphi(n) $。

你要求最小的点数那你直接按 $ \varphi $ 排一遍然后取前 $ m $ 个即可。

P4765 [CERC2014] The Imp

首先你要知道这个东西的转移顺序是什么。

设现在有两个物品 $ v_1,c_1 $ 和 $ v_2,c_2 $。

令 $ v_1 < v_2 $。

若按升序排列,$ ans=min(v_1 - c_1,v_2 - c_1 - c_2) $。

若按降序排列,$ ans=min(v_2 - c_2,v_1 - c_1 - c_2) $。

后面那个显然是不优的,所以应该按升序来转移。

然后 DP 即可,DP 的时候要注意顺着不好转移所以要倒着 DP。

CF1685C Bring Balance

自己想到了可以把左括号看成 $ 1 $,把右括号看成 $ -1 $,然后前缀和一遍,剩下就不知道怎么做了。

看题解发现答案的上界肯定是 $ 2 $,且方案为找到前缀和数组最大的那个位置,然后反转前面,反转后面。

证明可以自己画个图理解一下。

然后考虑什么时候答案可能是 $ 1 $。

你找到前缀和数组的第一个小于 $ 0 $ 的位置 $ fst $ 和最后一个小于 $ 0 $ 的位置 $ lst $。

再在 $ [1,fst] $ 中找最大值 $ max1 $ 和位置,在 $ [lst,n] $ 中找最大值 $ max2 $ 和位置。

如果可以翻转一次就成功,那么肯定是反转 $ [maxpos1+1,maxpos2] $ 这段区间。

和上面一样,反转过后区间加上了最大值,如果还小于 $ 0 $ 那就只能翻转两次了。

CF1085E Vasya and Templates

你直接用 $ dfs $ 暴力找,然后看一下有没有贴着上界或下界,然后直接像数位 DP 那样爆搜即可。

不知道为什么要放在贪心题单里面。

P1650 田忌赛马

又没秒掉,为什么数据范围还误导啊???我还以为是 $ n^2 $ 级别的算法???

你先给两个序列都排一遍序,然后直接双指针扫一遍,开头和结尾可以就直接统计,然后不能的话就用田忌的最小值去抵消齐王的最大值。

P4823 [TJOI2013] 拯救小矮人

好像做了好几道这种贪心确定 DP 转移顺序的了,还是不会。

你考虑高的小矮人如果早点出去了就不能对后面的造成贡献了,影响较大,矮的小矮人出去了影响较小,所以贪心地按照 $ A_i + B_i $ 进行从小到大的排序。

然后你考虑做一个背包,设 $ f_{i,j} $ 表示前 $ i $ 个小矮人走掉了 $ j $ 个,留下的小矮人垫高的最高值。

然后直接做就好了,背包可以优化一维。

UVA1747 Swap Space

调整法 + 分类讨论,当 $ a \le b $ 和 $ a > b $ 时的贪心策略是不同的。

当 $ a \le b $ 时:

现在有两对点 $ (a_1,b_1) $ 和 $ (a_2,b_2) $,令 $ a_1<a_2 $。

若 $ b_1 > a_2 $ 此时按 $ a $ 升序排序造成的贡献为 $ a_1 $,按 $ a $ 降序排序的贡献为 $ a_2 $,升序更优。

若 $ b_1 < a_2 $ 此时按 $ a $ 升序排序造成的贡献为 $ a_1 + a_2 - b_1 $,按 $ a $ 降序排序的贡献为 $ a_2 $,由于 $ a_1 < b_1 $,所以升序更优。

所以当 $ a \le b $ 时按 $ a $ 升序排序更优。

当 $ a > b $ 时:

现在有两对点 $ (a_1,b_1) $ 和 $ (a_2,b_2) $,令 $ b_1>b_2 $。

若 $ b_1 > a_2 $ 此时按 $ b $ 降序排序造成的贡献为 $ a_1 $,按 $ b $ 升序排序的贡献为 $ a_2 + b_2 - a_1 $,降序更优。

若 $ b_1 < a_2 $ 此时按 $ b $ 降序排序造成的贡献为 $ a_1+a_2-b_1 $,按 $ b $ 升序排序的贡献为 $ a_2 + a_1 - b_2 $,降序更优。

所以当 $ a > b $ 时按 $ b $ 降序排序更优。

AT_agc023_f [AGC023F] 01 on Tree

妙妙题。

你考虑每一次合并一个点和它的父亲所在的连通块。

令 $ cnt_{u,0/1} $ 表示 $ u $ 所在的连通块 $ 0/1 $ 的个数。那么这个时候造成的贡献即为 $ cnt_{fa_u,1} * cnt_{u,0} $。

现在的问题是以什么顺序来合并连通块才能使得这个总贡献最小。

其实刚刚算贡献的方式已经告诉我们该怎么做了。

如果要合并两个连通块 $ a,b $,那么当 $ cnt_{a,1} * cnt_{b,0} < cnt_{a,0} * cnt_{b,1} $ 的时候把 $ a $ 排在 $ b $ 前面是更优的。

所以直接这样排序即可。

P7287 「EZEC-5」魔法

比较智慧,反正我没秒。

你注意到乘法至多乘 $ \log $ 次就肯定可以了,所以这个的次数可以暴力枚举。

然后发现加法如果加 $ i $ 次就可以满足,那么加 $ i+1 $ 次也肯定可以满足,所以这个东西是有单调性的。

于是你直接二分加法的次数,暴力枚举乘法的次数就是对的,总时间复杂度是 $ \log^2 $ 级别的。

AT_agc029_c [AGC029C] Lexicographic constraints

本来以为贪心可以直接做的,调了两个小时发现不能直接贪心找答案。

注意到这个东西的答案有单调性,所以考虑二分答案。

考虑怎么检查答案。

如果下一位的字符串长度比这一位大,那么直接往后面填 1 就是对的。

否则就用线段树二分从后往前找第一个可以填的位置,给那个值加 1,然后把后面全部推平成 1。

如果找不到就说明这个答案是不合法的。

AT_arc103_d [ARC103F] Distance Sums

题解说的每一个条件都考虑到了,为什么没有做出来呢?

首先观察样例并结合直觉易得:\(D\) 最小的是整棵树的重心,\(D\) 最大的那几个是叶子节点。

然后根据典型的换根可以推导出换根之后 \(D\) 数组的变化公式,并且可以找到叶子节点的父亲。

剩下的就不会了

我好像有点蠢,找到叶子节点的父亲之后直接把叶子删掉,然后继续找下一个 \(D\) 最大的点即可。

如果找到的下一个点的 D 和推导出来的 D 不匹配那就说明不合法。

但这样找出来的树也不一定对,你最后还要 \(dfs\) 一遍判断构建出来的树是否合法。

然后就做完了。

CF1311E Construct the Binary Tree

还是没有自己想出来。

首先一个很显然的东西:最小深度和是完全二叉树,最大深度和是一条链。

然后可以根据这个东西去判无解。

然后考虑从一棵完全二叉树上去向链调整。

先扒出来一条最长的链,然后从大到小去枚举,试着将这个点尽量地向下放,每一次向下放 $ dep $ 都会多 1,所以如果合法的话那一定是可以构造出来的。

AT_hitachi2020_c ThREE

又是只想了一半的题。

你考虑一下要是不满足条件长什么样?

设 $ i,j $ 两点之间的距离为 \(3\),那么若它们不合法,一定是 $ a_i \equiv 1 \ (\bmod \ 3) $ 且 $ a_j \equiv 1 \ (\bmod \ 3)$ 或者 $ a_i \equiv 2 \ (\bmod \ 3) $ 且 $ a_j \equiv 2 \ (\bmod \ 3)$ 这两者中的其中一种。

你先给树黑白染色,然后分类讨论一下,令 $ x $ 为黑点数量,$ y $ 为白点数量,$ up $ 为 $ \lfloor \dfrac{n}{3} \rfloor $。

若 $ x > up $ 且 $ y > up $,这个时候黑点白点恰好可以覆盖所有的 $ a_i \equiv 1 \ (\bmod \ 3) $ 和 $ a_i \equiv 2 \ (\bmod \ 3) $ 的情况,所以给黑点变成 $ a_i \equiv 1 \ (\bmod \ 3) $,给白点变成 $ a_i \equiv 2 \ (\bmod \ 3) $,剩下的自由安排即可。

若 $ x \le up $ 这个时候覆盖不完,所以给原来黑点的地方放 $ a_i \equiv 0 \ (\bmod \ 3) $,白点和原来一样。

若 $ y \le up $,和上面一样,就不再赘述了。

P9755 [CSP-S 2023] 种树

有点妙。

首先你注意到这个答案是有单调性的,所以直接考虑二分答案。

二分出来一个答案 $ x $,考虑如何检查它是否可行。

写一个函数 $ calc(i,l,r) $ 表示第 $ i $ 个数在 $ [l,r] $ 天生长了多少米。

先预处理一个数组 $ up_i $ 表示第 $ i $ 个数在第 $ up_i $ 天的时候生长的长度小于等于 \(1\) 了。

那么 $ calc $ 函数分讨一下就写成这样:

inline int calc(int i,int l,int r) {
    if (r<up[i]) return ((l+r)*(r-l+1)*c[i]/2+b[i]*(r-l+1));
    if (l>up[i]) return (r-l+1);
    return (r-up[i])+((l+up[i])*(up[i]-l+1)*c[i]/2+b[i]*(up[i]-l+1));
}

然后现在要检查 $ x $ 是否可行。

对于每一个数 \(i\),检查若 $ calc(i,1,x) < a_i $,那么 $ x $ 就一定不行。

否则你再二分出对于一个数 $ i $,它最晚在多少天种下,到第 $ x $ 天能够满足要求。

然后你按这个东西排一下,从小到大处理每一个数。

要种下第 $ i $ 棵树,你首先要把它的祖先全部种下来。

模拟这个过程即可,若过程中有一个不满足要求了,这个 $ x $ 都是不合法的。

记得要开 __int128,然后就做完了。

P3423 [POI 2005] BAN-Bank Notes

可以直接多重背包,不知道为什么能过,反正就是过了。

正解的话可以直接用二进制分组优化,输出方案就直接拿个 \(bitset\) 记录一下每个 $ f_{j} $ 是否被选过。

P4563 [JXOI2018] 守卫

直接想歪了,本来以为可以单调栈,然后后面可以用线段树维护,结果其实并不能单调栈。

然后又想用 $ bitset $ 暴力维护它可以观测到的亭子,正确性和复杂度都不对。

正解其实是区间 $ DP $,考虑一段区间 $ [l,r] $,显然 $ r $ 是一定要放的,然后设 $ L_i $ 为 $ i $ 最左观测点。

那么 $ L_i $ 和 $ L_{i-1} $ 也是至少要放一个的。

然后后面区间 $ DP $ 即可。

P5504 [JSOI2011] 柠檬

\(DP\) 是显然的,$ f_i = max(f_j + cnt_{x,i}^2 \times x) $,这里显然要 $ a_i = a_j $ 不然肯定不优。

然后把那个拆开。

$ f_i = f_{j-1} + (cnt_{x,j} - 1)^2 \times x - 2\times cnt_{x,i} \times cnt_{x,j} \times x + cnt_{x,i}^2 \times x $

然后斜率优化板子题直接做即可。

P2890 [USACO07OPEN] Cheapest Palindrome G

看上去很简单的样子,但是我不会。

考虑一下区间 \(DP\),设 $ f_{l,r} $ 为 $ [l,r] $ 变为回文串的最小代价。

那么考虑一段区间向外扩张,$ f_{l,r} $ 可以由 $ f_{l+1,r} $ 和 $ f_{l,r-1} $ 转移过来。

然后若 $ s_l = s_r $ 那么也可以从 $ f_{l+1,r-1} $ 转移过来。

CF997E Good Subsegments

析合树。

首先建出析合树,然后将每个询问挂到对应的 LCA 上。

容易发现,儿子里面是有可能不包含在区间里面的。

所以总方案数容斥一下就是:子树总贡献 - 子树中左端点在 $ l $ 左边的贡献 - 子树中右端点在 $ r $ 右边的贡献 + 左端点在 $ l $ 左边且右端点在 $ r $ 右边的贡献。

然后这个东西你可以用树状数组维护。

P3177 [HAOI2015] 树上染色

挺好的树上背包。

设 $ f_{u,j} $ 为 $ u $ 子树内放了 $ j $ 个黑点的最大值。

考虑一下贡献的形式。

对于一条边 $ u,v $,将它断开分为了两颗子树 $ a,b $,那么经过这条边的黑白路径条数即为 $ a_0 * b_0 + a_1 * b_1 \((\) a_0,a_1 $ 分别为黑点和白点的数量)。

那么这样就可以 $ DP $ 了。

$ f_{u,j} = f_{u,j-k} + f_{v,k} + (k(m-k)+(siz_v - k)(n-m-siz_v+k)) * w $

然后注意一下转移的上下界即可。

CF2143D1 Inversion Graph Coloring (Easy Version)

好困难。

首先赛时很容易观察到一个事实,不能出现形如 $ i>j>k $ 且 $ a_i > a_j > a_k $ 这样的序列是一个好的序列。

那么最长严格下降子序列的长度小于等于 $ 2 $ 的序列即是好的。

考虑用 \(DP\) 维护这个东西。

设 $ f_{i,x,y} $ 为前 \(i\) 个数,最长严格下降子序列为 $ x,y $ 的方案数。

那么可以枚举 $ i,x,y $ 然后转移即可。

然后这个东西好像和 \(Dilworth\) 定理有关来着。

AT_abc424_f Adding Chords

感觉做过好多次和这个差不多的东西了,但还是记不住。

首先断环为链,你考虑相交的情况是什么样的。

令两条直线分别为 $ l_1,r_1,l_2,r_2 $。

若两条线相交,则 $ l_1 < l_2 < r_1 < r_2 $ 或者 $ l_2 < l_1 < r_2 < r_1 $。

那么你就查询左端点在 $ [l_1+1,r_1-1] $ 之间的最大的右端点是否大于 $ r_1 $ 或者右端点在 $ [l_1+1,r_1-1] $ 之间的最小左端点是否小于 $ l_1 $。

若满足,就不行,否则就可以。

CF1767F Two Subtrees

显然可以四维莫队,但这太蠢了。

想一下 dsu on tree 的过程,你每一次留下了重儿子的贡献,删除了轻儿子的贡献,这个操作的序列的长度是 \(n\log n\) 的。

那也就是说,你可以在带删除的条件下,用一个前缀来刻画一棵子树。

这样,莫队维护的指针就只有两个了,用值域分块维护区间众数。

感觉这个用前缀来刻画子树的东西很有用啊!

CF893F Subtree Minimum Query

发现一位信息难以刻画这个一个,考虑用两维信息来维护。

用 $ [dep_i,dfn_i] $ 来刻画一个点。那么查询等价于第一维 $ [dep_i,dep_{i+k}] $,第二维 $ [dfn_i,dfn_{i+siz_i-1}] $ 范围内查询最小值。

二维矩形最小值随便做。

感觉这个用多维信息来刻画点的思维也很有用啊!

CF1656E Equal Tree Sums

妙妙构造题。

考虑对树黑白染色,若一个点是黑点则权值为度数,否则权值为度数的相反数。

证明一下为什么是对的。

考虑对于一条边,它造成的贡献是 1 和 -1 因为它连接的两个点的颜色显然是不同的,所以总权值肯定是 0。

对于每一个点我们都钦定它是根节点,删除它之后每一个儿子的权值也是 0。

因为在删除它和儿子这条边之前,他和儿子之间的这条边的贡献是 1 和 -1,那么删除之后对儿子的子树的权值是没有影响的。

AT_abc423_f [ABC423F] Loud Cicada

学生高一就学会了二项式反演,你也来试试吧!

首先你发现你可以 $ 2^n $ 枚举所有的 $ m $ 种蝉是哪些。

欸但是你发现枚举的 $ m $ 种不一定只有 $ m $ 种,是至少 $ m $ 种。

已知至少 $ m $ 种的方案,求恰好 $ m $ 种的方案,这个是二项式反演板子。

CF2152G Query Jungle

有点神奇。

可以动态 DP,但是我忘了。

你发现答案是子树内没有怪物的节点数的和,然后就可以用括号序来刻画这个东西。

合法的那个节点一定是这样 () 的。

这个可以用线段树维护,维护两个线段树,一个是有怪物的,一个是没怪物的,修改就是交换左右子树。

然后就做完了。

P4310 绝世好题

一直做 DS 题,脑子已经被吃掉了。

考虑对于每一个二进制位进行考虑,可以从先前的有 1 的地方转移到这个数其它有 1 的地方。

即:

int x=e[i],len=0,maxx=0;
while (x) {
    if (x&1) maxx=max(maxx,f[len]);
    x>>=1,len++;
}
len=0,x=e[i];
while (x) {
    if (x&1) f[len]=max(f[len],maxx+1);
    x>>=1,len++;
}

MZOI 20251006【CSP】模拟 直径(diameter)

好奇妙的 DS,记录一下。

有一个关于直径的定理:对于两个点集的直径端点 $ a,b,c,d $,这两个点集合并后的直径的端点仍是这四个点中的两个。

这样就可以 $ O(\log n) $ 的时间来合并两个点集的直径。

考虑到切割边实际上是切掉一棵子树,子树的区间是不交的,我们可以用线段树在 \(dfn\) 序上来统计答案。

切掉 $ k $ 条边形成的路径上界是 $ 2k -1 $ 条的,所以我们直接统计就是对的。

P5104 红包发红包

很好主包现在开始恶补期望。

有一个结论:从 \([0,x]\) 中随机选择一个数,这个数的期望值是 $ \dfrac{x}{2} $。

那么第一次剩下的期望就是 $ \dfrac{x}{2} $,第二次剩下的期望就是 $ \dfrac{x}{4} $ …… 以此类推,第 $ k $ 次的期望就是 $ \dfrac{x}{2^k} $。

P2964 [USACO09NOV] A Coin Game S

挺厉害的一个博弈论 DP。

\(f[i][j]\) : 现在取到了第 \(i\) 个数(第 \(i\) 个数未取),当前取币上线为 \(j\) 的最大值。

然后就可以记忆化搜索。

CF1223F Stack Exterminable Arrays

突然发现以前做过的一个很牛的题的一个很牛的做法。

CSP-S 2023 T2

你发现能删除的一段区间是满足结合律的!

然后还有一个东西也满足结合律,那就是矩阵乘法!

那这就很好了,你给每个数随机一个矩阵出来。

若一段区间的矩阵乘积是单位矩阵,那就说明这段区间可以被消完。

那么问题就转化为了求有多少段子区间的乘积为单位矩阵。

这个用个 \(map\) 维护即可。

AT_abc228_h [ABC228H] Histogram

斜率优化。

注意到写斜率优化的前提条件是会写暴力 DP(

注意到题目等价于将排好序的序列划分成一个一个的段,每个段内的数都加到最后一个数。

所以暴力 DP 的式子即为 :

\(f[i] = f[j] + x + \sum\limits_{j=k+1}^{i} (a[i]-a[k])*c[k]\)

你给后面那个求和用前缀和表示出来,后面的就是标准的斜率优化了。

P2497 [SDOI2012] 基站建设

斜率优化。

难点在于几何(

alt text

由上面这图可知, $ (r_1 - r_2)^2 + (x_2-x_1)^2 = (r_1 + r_2)^2 $。

然后你转化一下就得到 $ \sqrt{r_2} = \dfrac{(x_2 - x_1)}{2 \sqrt{r_1}} $。

状态转移方程就很简单了 :

$ f[i]=\min(f[i],f[j]+\dfrac{x[i]-x[j]}{2\sqrt{r[j]}}+v[i]) $

转化一下就成斜率优化板子了。

posted @ 2025-09-19 11:48  LittleFoxFairy  阅读(10)  评论(0)    收藏  举报