以前的杂题 solution
PE Lesson
考虑到这些 2 个交换机会的人比较吊,随便选位置。
剩下的人随便选位置就好了,考虑 dp 一下。
\(dp_i = dp_{i - 2} * (i - 1) + dp_{i - 1}\).
那么就是 \(\frac{f_{A} * N!}{(b - 1)!}\)
Score of a Tree
\(a_u\) 在 \(t\) 时刻的权值,其实是 \(t\) 级儿子的异或和。
对于任意一种 \(A\), 那么他最多会在 \(dep_v + 1\) 时刻变成 \(0\), 那么他可以产生的贡献为 \(dep_v + 1\),其中 \(v\) 是 \(u\) 的长儿子。
然后我们考虑统计直接算所有的 \(F(A)\),方案显然不容我们用一些常见的技术手段如容斥来计算。
考虑对称性,一个状态全取反,那么我们就可以发现状态完美重叠,答案就是 \(2^{n -1}\sum dep_v + 1\).
CF960F 复健
直接讲做法罢。
考虑固定最好固定的编号这一维,那么我们记录此时 \(f_{u, w}\) 表示走到 \(u\) 节点的最大权为 \(w\)。
那么考虑 \((u, v, w)\) 有如下转移 :\(f_{v, w} \gets f_{u, w'} + 1\)。
显然这是一个最长上升子序列的形式,可以用线段树维护,然后需要注意的是这个 \(u\) 和 \(v\) 不是同一棵树,可以考虑动态开点。
P4590
考虑观察 lcs 的形式,发现其实 \(lcs_{i, j}, lcs_{i , j-1}\) 的差是 \(\in [0, 1]\)。
发现这个是可以状压的,我们可以记录 \(f_{pos, st, k}\) 来表示长度为 pos, \(lcs\) 状态为 st, \(NOI\) 匹配到第 k 位。
然后考虑转移的时候求出 lcs 的新状态。时间复杂度应该是 \(nk2^k\) 的。
这个东西有一个好听的名字叫做 dp of dp.
CF1637F Towers
思考一下,肯定是在叶子上面填数。
那么叶子上面填的最大、次大肯定比根大。为了更好的利用填数,不妨让最大的为根。
然后递归子树求出其最大、次打,暴力合并帅不帅?
XOR Tree CF1709E
考虑每一棵子树合并上来的结果。
那么如果 \(a\) 可以赋值任意值,不妨依次给其标号。
那么 \(a_u = 2^{tag}\), 其中 \(tag \ge 114514\).
这样是一定合法的。
那么我们发现这样就相当于是枚举每个点的子树,发现其有任意一颗子树不合法,将这个根打上 tag 是最优秀的,而不是儿子。
那么子树内的节点不用考虑,可以启发式合并解决。
CF Three Occurance
考虑到对于每一个元素单独考虑贡献。
那么就是记录前驱,每次让一段区间非法,让一段区间合法。
这个可以具体看代码。然后左端点是单调的,那么就是线段树考虑合法区间的个数了。标记永久化可以研究一下。
CF1093G Multidimensional Queries
这个东西大概是 trick 的结合体罢!
有一个经典的曼哈顿 trick 叫做拆位。
考虑状压,然后 0 带有 -1 的系数。
这样若干个东西取个补集加起来拿个线段树维护就可以了。
看守。
Ants in Leaves :
除去限制显然答案就是 \(\max dep_v\), 其中 \(v\in leaf\)。
那么只有根节点没有限制,考虑将其子树拆分后合并。
那么注意到,按 \(dep\) 排序,相同的两个点只能同时上去一个,so?
CF 922E
一般的 dp 方程是 :
\(dp_{i, j}\) 表示前 \(i\) 棵树有 \(j\) 点魔法的最多有几只鸟。
那么可以用这个来表示出 \(B\).
考虑我们常用套路,交换目标和一个位置。
\(dp_{i, j}\) 表示前 \(i\) 棵树有 \(j\) 只鸟已经被抓捕的最大魔法值。
做个二进制拆分背包就可以了。
P8595 「KDOI-02」一个网的路
补一下题解,题意非常明了。
自己做题的时候忘记了对于 \(v_1,v_2 \in u\) 构成一条链的讨论,还是吧台行。
考虑一条链有 3 种形态,对于链顶 \(u\) :
-
- 只有 \(u\) 一个节点。
-
- 他的一个儿子 \(v\) 连着他。
-
- \(v_1, v_2 \in u\) 构成了一条先上后下的链。
考虑记录 \(f_{u,{0/1/3}}\) 为这三种情况的最优解。
考虑如下转移 :
然后就做完了
CF1486D Max Median
众数,懂?
二分答案, 1,-1, 前缀最小值。
中位数的中位数。
二分答案,判断子段,贡献差值 \(1,-1\), 新生舞会?
CF940E Cashback
首先等价于求最大被删值。
\(\rm Key\) $\rm Observation : $ 每段长度 \(l\) 一定是 \(c\) , 证明 :
-
\(0 \le l < c :\) 没有产生贡献。
-
\(l \geq c :\)
令这段区间排序后为 \(b_1...b_{r - l + 1}\)。
首先 \(l\) 一定不是 \(k * c + m\) 的形式,这样的最小值只会更小。
那么 \(l = k * m\) 这样的形式下,\(b_k\) 显然是不如每一段贡献的和。
因为这样可以拆成 \({b_1, b_2, b_3 ...b_k}\), 而考虑强制钦定 \(b_i\) 就是那一大段区间的第 \(i\) 小。
显然 \(\sum b_i > b_k\)。
最终得到状态 \(f_i\) 为以 \(i\) 结尾的的最大被删值。
\(f_i = \max\{f_{i - 1}, f_{i - m} + \underset{k \in {[i - m + 1, i]}}\min a_k\}\)
这个是一个单调队列的转移形式 \(O(n)\)。
P8575
模板题也敢放?
你这属实 8 行。
考虑到, 对于 \(dfn_v \in [dfn_u + 1, dfn_u + siz_u - 1]\) ,那么 \(v\) 就在 \(u\)
的子树内。
分别的,我们记录这个闭区间的左右端点为 \(l_u,r_u\)
题目要求是 :
其中 \(f(u, v)\) 若是 \(red_v, blue_v\) 都分别小于等于 \(red_u, blue_u\) 则返回 \(1\)。
考虑拆出来 \([1, l_i), [l_i, r_i]\)
来相减, 这是一个三维偏序的形式。
CF958B2 Maximum Control
双倍经验 : BZOJ3252.
考虑到选了 \(k \in [2, n]\) 个点, 会形成最多 \(k\) 条链。
考虑长链剖分,每一个点都能被一条长链不重地覆盖。
于是我们在长链剖分时将每一条长链塞入堆里,然后答案相加就可以了。
Number of Components :
V - E 老套路了。
求 \(V\) 的所在区间个数,再考虑两边 min 和 max 的区间。
Yet Another Minimization Problem
决策单调性板子。
CF 1553G
观测到答案不超过 2.
\(a_i(a_i+1), a_j(a_j+1)\) 二者肯定是 2 的倍数。
你这个数据范围这么小,筛法筛出所有质数因子。
我们再判断建出的点是否是一个连通块的就行了嘛 (
一般的 dp 方程是 :
\(dp_{i, j}\) 表示前 \(i\) 棵树有 \(j\) 点魔法的最多有几只鸟。
那么可以用这个来表示出 \(B\).
考虑我们常用套路,交换目标和一个位置。
\(dp_{i, j}\) 表示前 \(i\) 棵树有 \(j\) 只鸟已经被抓捕的最大魔法值。
做个二进制拆分背包就可以了。
CF1486D Max Median
众数,懂?
二分答案, 1,-1, 前缀最小值。
中位数的中位数。
二分答案,判断子段,贡献差值 \(1,-1\), 新生舞会?
P2943 DP
非常优秀的一个性质 :
所有区间都不能有超过 \(\sqrt n\) 个颜色, 否则会比以每个元素划分劣。
我们定义 \(pos_{i, j}\) 表示 \([pos_{i,j}, i]\) 有 \(j\) 个颜色, 然后考虑维护
这个方程。
咋维护 \(pos_{i, j}\) 呢? 我们发现随着 \(i\) 的增长, \(pos_{i, j}\) 是单调不降的, 考虑动态维护这个指针就可以了。
考虑到一个数组 \(x\) 的贡献为 :
略微展开得到 :
CF1637D
定义 在右半边 为有序点对 \((u, v)\) 产生贡献时,因为 \(v > u\) ,\(v\) 则被称为在 在右半边的 , 那么, 左半边的定义也照猫画虎。
考虑到对于第 \(i\) 个位置上的元素 \(x_i^2\) 会出现在 \([1,i-1]\) 的右半边, 和 \([i+ 1,n]\) 的这一部分则会在其作为左半边的时候的右半边。
那么可以化简得 :
右边这个牵扯了两项显然不太好计算可以稍微做做手脚 :
我们记 :
标志性的, 我们记录 \(a\) 数组的为 \(suma_i\) , \(b\) 数组同理。
合并得 :
带入得:
显然这个问题变为了最优化后面那个东西 :
咋做捏 : 我们考虑对于 \(i\) 一定, \(suma_i\) 和 \(sumb_i\) 是可以互相转化的, 一个有前途的 DP 就出来了 (有没有感觉有点像那个牛马 \(\rm varience\) DP 题) :
考虑到往前填往后填没啥区别, 所以这里默认往前填, 我们设 \(f_{i,s}\) 为 \(a\) 数组填了 \(i\) 位, 和为 \(s_a\) 的最小值。
快乐暴力转移就完了 😄 , 具体实现可以看其他题解。
CF1680C Binary String
赛时看错题选手报道, 提供一个无脑解法。
我们记录 \(pre_{i, op}\) 表示 $[1, i] $ 出现的 \(op\) 个数, \(suf_{i, op}\) 表示 \([i, n]\) 出现的 \(op\) 个数。
特定的, 我令 \(s_0 = pre_{n, 0}\)
我们发现,对于前缀 \(a\) , 后缀 \(b\) 所表示的答案是 :
- 较为暴力的 method :
考虑对于左右两边加上 \(pre_{a, 0} + suf_{b,0}\) 得到 :
我们分类讨论.
- 1.\(s_0 \leq pre_{a,1} + suf_{b, 1} +pre_{a, 0} + suf_{b,0}\) 的情况
\(pre_{a,0} + pre_{a, 1}\) 是 已知的, 考虑求 \(suf_{b, 0} + suf_{b, 1} \geq s_0 - pre_{a,0} - pre_{a, 1}\) 的最小 \(suf_{b,1}\) 。
- 1.\(s_0 > pre_{a,1} + suf_{b, 1} +pre_{a, 0} + suf_{b,0}\) 的情况
\(pre_{a,0} + pre_{a, 1}\) 是 已知的, 考虑求 \(suf_{b, 0} + suf_{b, 1} < s_0 - pre_{a,0} - pre_{a, 1}\) 的最大 \(suf_{b,0}\) 。
比较暴力的方法是, 考虑倒序枚举去确定 \(a\) 的位置, 直接开线段树去分类讨论维护这个题。
- 较为优美的 method :
但是我们发现, 其实这个题没有这么麻烦, 拎出来这个式子 :
为了方便地比较大小, 左右作移项得 :
发现可以继续合并 :
那么就是看左右哪个大的大小取值。
考虑到 \(pre_{0/1},suf_{0/1}\) 单调不降。
考虑枚举 \(a\)。
如果左边大那么就是取 \(s_0 - pre_{a, 0} - suf_{b,0}\) , 那么肯定 \(b\) 越大越好, 因为 \(a + b \leq s_0\) 考虑令 \(b = s_0 - a\) .
如果左边大那么就是取 \(pre_{a,1} + suf_{b, 1}\) , 那么肯定 \(b\) 越小越好, 因为 \(a + b > s_0\) 考虑令 \(b = s_0 - a + 1\).
所以我们有 \(O(n)\) 做完这个题。
- CF149D :
用 \(f_{l,r,p,q}\) 表示一个区间 \([l,r]\),左右端点的状态分别为 \({p,q}\) 时的方案数。然后考虑分类考虑是否括号匹配,
用记忆化搜索 \(dp_{l,r}\) 来求一个区间的方案数,加法原理 + 乘法原理即可。
- CF1036C
数位DP. 用\(f_{pos,cnt}\) 代表第 \(pos\) 位,有 \(cnt\) 个非零位的方案数。然后套模板。
- P3244
组合数题,首先 \(\rm DAG\) 的答案为 \(\prod_{i = 2} ^{n} in_i\)
然后我们考虑计算环 \(\rm S\)上的不合法答案 :\(\sum_{S}\prod_{i\notin S} deg_i\).
然后用个 DP即可。
- P2523
组合数题。 设 \(f_{j,k}\) 为第 \(j\) 个座位,后面有 \(k\) 个人。
\(f_{j,k} = \sum_{k} f_{j+1,j-k}*C_k^j\),注意一下边界即可。
【贪心二分/AT1807】 食塩水
-
题意:选取 \(\rm k\) 瓶盐水,使得其混在一起含盐量最大。
不妨转化为二分最大值判定,然后就会有一个像 \(01\) 分数规划的东西:
\(\rm S\) 表示的是所选的集合。
显然,我们可以用一个非常套路的 \(\rm ans\) 来表示这个式子的值。然后进行转化。
方便表达其中的算式,令
然后我们不妨二分一下 \(\rm ans\) 的值,然后二分对 \(\rm val\) 数组取前 \(k\) 大累加,看一看是否大于 \(0\) 即可。
【CSP2019】划分
今天,smzx的学长 ywq 给了我这一道题 (
我们设 \(f_{j,i}\) 为以 \(j,i\) 为最后一段的最小值。
\(f_{j,i}=\underset{0\leq k < j,s_j-s_k\leq s_i-s_j}{min}{f_{k,j}+(s_i-s_j)^2}\)
然后我们就有了 \(n^3\) 的 solution.
然后我们可以整理一下 :
\(f_{j,i}=\underset{0\leq k < j,s_j-s_k\leq s_i-s_j}{\min}\{f_{k,j}\}+(s_i-s_j)^2\)
我们直接可以发现,分段越靠后,平方项就越小 (
我们设 \(pos_i\) 为最后一段,以 \(i\) 结尾,最优秀的 \(j\)
我们领出来上面式子 \(s_j-s_k\leq s_i-s_j\) 发现可以表示为: \(s_j-s_{pos_j}\leq s_i-s_j\) 移项得 \(2s_j-s_{pos_j}\leq s_i\). 我们可以拿个式子表示一下
\(val(j)=2s_j-s_{pos_j}\) 然后我们就有了 :
\(pos_i=\underset{val(j)\leq s_i}{\max}{j}\) .
我们发现我们对于前后两个位置 \(x,y\) 如果有 \(val(x)\leq s_i,val(y)\leq s_i\) 根据我们提及的性质,显然 \(y\) 是更加优秀的。
然后有因为有单调性就单调队列.
- CF739B :
我们维护每个点\(u\)的深度 \(dep_u\)。然后我们求的是
\(dep_v-dep_u\leq a_u\) ,转移可得 \(dep_v\leq dep_u+a_u\)。 离散化+树状数组。
- CF833B :
我们直接设 \(f_{i,j}\) 为结尾为 \(i\) ,第 \(j\) 段的最大值。
因为没有同颜色的一段才有贡献,所以我们记录 \(pre_i=\underset{seq_j=seq_i}{\max}{j+1}\) 。然后我们直接可以得到 : \(f_{i,j}=\underset{pre_i\leq k}{\max}{f_{k,j-1}+1}\)。
- CF314E :
转换成为左右括号计数 :
设 \(f_{i,j}\) 表示结尾为 \(i\) 剩下 \(j\)个括号配对的方案数。然后暴力转移,我们发现\(j\)小于\(i\)的一半,然后再加上滚动数组滚成 \(f_j\) 。
- P3730 && P4396
喜闻乐见的数据结构,莫队+值域分块 \(O(1)\) 修改
- P4556
树上差分+线段树静态合并
- P2607
考虑使用和“城市环路”同样的解题思路,然后拆环跑最大独立集。
- P2633
倍增LCA查询路径+主席树第K大
- CF 891C
首先有2个结论 :
对于任意权值的边,所有最小生成树中这个权值的边的数量是一定的
对于任意正确加边方案,加完小于某权值的所有边后图的连通性是一样的
然后我们发现,只用处理同一权值的边的连通性即可。我们不妨在 Kruskal 时处理同一权值的边上的点所在联通块,如果发现不同的联通块,我们就可以加入生成树。
然后照猫画虎(引用自Ghastlcon),我们可以在询问时处理每条边的联通块是否成环即可。
- CF1311E
构造题,我们考虑最终结果 \(R\) 在一条链 \(L\) 和完全二叉树\(T\)之间 。否则无法构造 。那如果可以构造呢?我们考虑将 \(R\) 最底下的儿子 \(k\) 提到可以提到的上方(越上越好)然后我们就另深度减去变化量,当深度和为\(d\)时,我们就构造完毕了。当然,我们也可从\(T\) 变为 \(L\) ,我们可以按照线段树左右儿子命名规则建出 \(T\) ,然后再将底下的节点按照编号大到小提到链上。
- P7789
大概是本文截至这道题最难的题。
完全图考虑删边构造最小生成树。
我们通过手玩可以证明 $dis_{u,v}=\underset{u,v}{\max} a $ \(\rm{mod}\) \(\underset{u,v}{\min} a\) 。 然后,我们可以证明对于 \(k*a_i\leq a_b\leq a_c\leq (k+1)a_i\) 中,选 \(b\) 连边是最优的。因为我们如果连 \(c\) 的话,会产生更多的贡献。 所以我们只需枚举 \(limit\) 暴力连边,就做完了。
超级毒瘤结论题。比赛打了 30pts 暴力跑路。
- P5290
久仰大名,首先做法事启发式合并,结论事将两条链分别取最大值出来合并,丢进优先队列,因为这样,我们避免了次大值产生多余的费用。然后就做完了。
- P4735
可持久化01Trie,考虑维护一个前缀和,然后可以直接在树上贪心求得最大值。
- P4630
考虑建出圆方树,然后我们可以利用 bdfs 来的性质 :
-
对于属于一个点双联通分量的任意点对\((u,v)\)以这个点双联通分量除了\(u\)和\(v\)以外的任何点作为中间点,都存在一条合法路径
-
若圆方树上的点对之间的路径(显然树上路径是唯一的)经过一个点双联通分量,则这个点双联通分量内的每一个点都能当做中间点(即题中的点 \(c\))。
然后就是一个显然的树形 DP 了。
- CF125E
如果没有学过 \(\rm wqs\) 二分,这个将是思维难度最高的题目。之前钟皓羲给我讲了一个类似的题目,但是用的是根号分治,现在忽然记起来,好像也有这一道题。
比如:有白边和黑边,求恰好有 \(\rm k\) 条白边的最小生成树。
Solution: 令所有的白边减去一个 \(\rm delta\) ,然后就可以二分 \(\rm delta\) 来构造。
其实这一道题目也是这样,我们考虑建模成上一道题,将与 \(1\) 相连的边看作白边,然后二分 \(\rm delta\) 后构造答案即可。
- CF115E
\(f_{i,j} = f_{i-1,j} -cost_i+\sum_{R_k=i}p_k\) 这个是显然的。
然后线段树优化 DP 即可。
- P3521
逆序对 + 线段树合并。
在线段树合并时讨论左右子树产生的贡献即可
- P3147
莫队 + 值域分块。用分块暴力扫到没有所有数都有的块,朴素维护小块。
- CF208E
使用长链剖分维护 K 级儿子,然后 K 级祖先可以在 Dfs 中求.
- AT2698 :
手写一个子序列自动机,跑BFS即可 (如此暴力)。
- P7114 :
考虑使用 hash 维护循环节,然后在用一个树状数组维护方案数,然后就可以做到 \(O(n\ln n )\) + \(O(n\log26)\),卡卡常可以过 ()。
- CF383E :
补集转化 + 做高维前缀和 + 容斥原理即可。
- P4799
折半搜索 + 二分查找暴力匹配即可。
- P4198
首先转化为看斜率,然后就是带修最长上升子序列。拿一棵线段树维护即可。
- CF620E :
首先做 \(dfs\) 序, 然后发现只有 \(60\) 种颜色, 于是可以愉快的用状压来做 \(\rm Maintain\), 线段树即可。
- CF383C :
考虑 \(dfs\) 序, 然后树状数组按照深度奇偶性计数,最后差分就可以干爆区间修改,单点查询.
当然,也可以建两棵树,树链剖分两次再重叠。
- AT4519
引理
每个元素要么不操作,要么操作一次
用 \(f_{i,j}\) 表示到 i, 以 j 结尾的最小方案.
if (a[i] > j) f[i][a[i]] = min(f[i][a[i]], f[i - 1][j]), f[i][j] = min(f[i][j], f[i - 1][j] + A);
else f[i][j] = min(f[i][j], f[i - 1][j] + B);
- P3302
考虑第一个操作用主席树树上差分,第二个可以启发式合并,于是就可以在暴力合并时处理倍增 LCA,故有 \(O(n\log^2 n)\)。
- CF842D
2000 + 的数据结构捏 /qq
考虑 01Trie.
- CF545E
2000 + 的伞兵题捏 /cy
建棵树就可以了, 注意松弛是 >=
- CF1076D
建棵树就可以了, dfs 一下就可以了。
- CF865D
反悔贪心。
两类 :
-
取回之前的一组代替一下
-
找一组合并一下
发现可以神仙的合并到一个堆里捏。
- CF1151E
森林 /cy
考虑转化 \(V - E\), 然后考虑一次次插入贡献到 \(f(l, r)\) 里面的哪些地方 /kk
- P7961 && P7962
后面那个等会补, 前面这个可以考虑 4 维 DP, 刷表 !!.
\(f[pos + 1][i + x][(j + x) / 2][k + (j + x) % 2] += f[pos][i][j][k] * c[n - i][x] % MOD * v[pos][x] % MOD; f[pos + 1][i + x][(j + x) / 2][k + (j + x) % 2] %= MOD;\)
- CF1202E
贺的。 考虑建个 ACAM 正反跳一下, 维护划分点就可以力 /qq
- CF1106E
自己讲过这个牛马题, 拿个堆维护决策, 刷表!!
f[i + 1][j + 1] = min(f[i + 1][j + 1], f[i][j]);
if (d[i]) f[d[i] + 1][j] = min(f[d[i] + 1][j], f[i][j] + w[i]);
else f[i + 1][j] = min(f[i + 1][j], f[i][j]);
- P5838
有没有一种可能 ? 这个题是生活在树上削弱版.
- CF1009F Dominant Indices 暴力合并子树 :
设\(f_{u,k}\)为u子树下的深度为\(k\)的儿子总数。
然后,做统计的时候,我们直接暴力获得答案。
- P3565 [POI2014]HOT-Hotels 树上DP+暴力维护状态
- BZOJ3252 攻略 :
贪心,取前k条长的长链

浙公网安备 33010602011771号