2024.4.23 近期练习
CF1924D
先考虑一个串的最长合法序列,维护一个栈,答案就是右括号加入时栈非空的次数。
我们看成从 \((0,0)\) 走到 \((n,m)\),发现没被匹配的右括号个数就是 \(x-y\) 的最大值。
要想只有 \(k\) 个匹配,那么要和 \(x-y=m-k\) “相切”。
若 \(f(k)\) 表示穿过直线的方案数,答案是 \(f(k)-f(k-1)\).
考虑像算卡特兰数,在折线与 \(x-y=m-k\) 第一个交点处,将之后的折线关于直线翻转。
终点变成了 \((n+m-k,k)\),方案是 \(C_{n+m-k+k}^k=C_{n+m}^k\),
这里的方案与满足前面条件的折线都构成双射关系。
CF1930F
若只有两个元素我们来考虑做法,设它们为 \(a,b\),我们假设最后是 \(a|x-b|x\).
每位贪心,对于第 \(i\) 位,有且仅有若 \(a=1,b=0\),则这位取 \(0\) 时有贡献。
也就是 \(a|b-b\),\(a,b\) 反过来就是 \(a|b-a\).
至于一个集合我们考虑枚举 \((a,b)\),我们每加入一个 \(a\),都考虑前面对其贡献。
若是 \(a|b-b\) 呢不好算,注意到 \(a+b=a|b+a\&b\),所以就是 \(a-a\&b\).
只需要计算 \(a|b\) 的最大值和 \(a\&b\) 的最小值。按位贪心,每次查询是否存在 \(b\) 以 \(x\) 为子集。
这个暴力更新,记忆化搜索,是只有 \(O(n)\) 次更新的。
CF1943D1/2
考虑差分,然后选两个不相邻的数,前者 \(-1\),后者 \(+1\),这是个匹配问题。
我们考虑用前面的正数匹配后面的负数,那么对于每个 \(i\) 分别考虑,
若 \(-c_i\le \sum_{j\le i-2} c_j\), 则 \(i\) 可以匹配前面剩下的(看做是 Hall 定理)。事实上,也就是 \(a_{i+1}+a_{i-1}\ge a_{i}\).
设 \(dp_{i,j,k}\) 表示考虑了 \(i\) 位,前两位是 \(j,k\) 的方案数,考虑用前缀和优化。
Hard version 考虑容斥,设 \(f(i)\) 表示钦定 \(i\) 个不合法,答案是 \(\sum_{i=0}^n(-1)^if(i)\).
设 \(dp_{i,j,0/1}\) 表示考虑了 \(i\) 位,上一位是 \(j\),当前不合法个数的奇偶性的方案数。
若当前这位不钦定,那么 \(k\) 随便填,\(dp_{i,k,0/1}=\sum dp_{i-1,j,0/1}\)。
若钦定不合法,若是知道了 \(a_i,a_{i+2}\) 的值,\(a_{i+1}\) 取值范围就已知,
\(dp_{i,j,k}=\sum_{t=1}^mdp_{i-2,t,-k}\times (m-t-j)\)。前缀和优化。
CF1909F1/2
如果我们把 \(i\) 放到第 \(j\) 个位置,那么会对 \(\max(i,j)\sim n\) 做贡献。差分出来每次做贡献就是单点加。
那么我们对于 \((p_1,p_2,..p_n)\) 这个排列,对于每个 \(\max(i,p_i)\) 的个数都是被固定的。
如果要填 \(j=\max(i,p_i)\),两种方法,取一个 \(i\le j\),令 \(p_i=j\);或者是取一个 \(i>j\),使 \(p_j=i\).
所以我们发现差分出来每个位置的值 \(\in [0,2]\)。
若是 \(1\),有 \(2(i-a_{i-1})-1\) 种填法,若是 \(2\),有 \((i-a_{i-1}-1)^2\) 种。每填一个都分别占用一个 \(i,p\)。
考虑 Hard version。我们可以把这个问题放到棋盘上考虑,也就是在棋盘上放车。
我们把 \(-1\) 的连续段提出来,考虑一个 \(a_i\neq -1\) 的位置以及其前面第一个 \(a_j\neq -1\)。
相当于在边长 \(x=i-a_j\) 正方形,去掉左上角 \(y=j-a_j\) 的正方形,放 \(t=a_i-a_j\) 个车的方案数。
拆成一个大矩形,一个小矩形,方案数是 \(\sum_{k=0}^t C_{x-y}^kC_{y}^k k!\times C_{x-y}^{t-k}C_{x-k}^{t-k}\times (t-k)!\).
CF1913F
我们枚举回文中心,二分哈希,可以找到一个位置 \(p\),若是将 \(s_p\) 改成 \(c\),就会多一些回文子串。
但是我们如果把 \(s_p\) 改成了 \(c\),会减少子串,也就是经过 \(p\) 的且 \(p\) 不是回文中心的回文子串个数。
假设回文中心为 \(mid\),半径为 \(r\),对于所有点 \(x\),经过 \(x\) 的子串个数是等差数列。两次差分维护。
最后计算答案枚举即可,注意字典序最小需要讨论。
CF1904F
考虑拓扑排序,对于每一条限制看成某个点大于/小于路径上的所有点。
那么有解就是没有环。连边的话考虑优化建图,考虑用倍增即可。
CF1935F
先考虑一个问做法。若 \(u\) 只有一条出边,没影响。
若 \(u\) 有两条出边,除非 \(u\) 点把两个部分从中间分开,否则这两个部分必有距离为 \(1\) 的。
\(m\) 条出边则最多是 \((m-1)+1\) 的代价,这个 \(+1\) 来自于 \(<v\) 的和 \(>v\) 的之间联通需 \(2\) 的代价。
麻烦的是构造方案。钦定 \(1\) 为根。我们先把所有 \((i,i+1)\) 挂在其 \(lca\) 上。
假设我们处理点 \(u\),我们先把在 \(u\) 上的这些 \((i,i+1)\) 尽可能合并(并查集)。
对于 \((i,i+1)\) 分别处于点 \(u\) 子树内外的怎么办呢?
我们对于每个子树维护这个子树内可连接的 \((i,i+1)\),取其中 \(lca\) 最浅的点,看是否比 \(u\) 浅。
若满足条件那么就可以连上去。最后看是否联通,不连通就连 \((v-1,v+1)\) 这条边。
要使用可撤销并查集。
CF1917F
我们的想法是先构造出一条链为直径,然后把剩下的边全部挂在这条链最中心的点上。
我们发现若存在两条边加起来超过 \(d\),那么势必不合法。
我们假设直径的边的集合是 \(S\),使 \(\sum S_i=d\);将 \(S\) 分为两部分 \(S1,S2\),设 \(|\sum S1_i-\sum S2_i|\) 最小为 \(c\),
那么若 \(\max(U-S)\le \dfrac{1}{2}(d-c)\) 合法。条件很复杂。
关键是,我们注意到,若是 \(\max(U-S)\) 的值为 \(U\) 的最大值或次大值,才可能不合法。
变成了一个二维可行性背包,bitset 优化,\(O(\dfrac{n^3}{\omega})\).
我们先把前 \(n-2\) 小的全部做背包,然后判断即可。
CF1942F
我们注意到每个 \(f(i)\) 都向下取整就可以避免浮点数运算。
我们考虑扫描线,把操作全部离线,用数据结构维护每次修改的答案。
我们从前往后枚举 \(a_i\),维护当前每个询问的值 \(f_i\),对于 \(a_i\) 每个值存在的时间,区间加和全局开根。
势能线段树,每个区间维护 \(\max,\min\),全局开根的话暴力递归,直到 \(\max-\min = \sqrt{\max}-\sqrt{\min}\).
此时可以把根号标记用加法标记表示了。复杂度证明未知。
所以我们采用分块的做法,如果一个够长的块,那么无论前面带入什么值,后面都会稀释成 \(\Delta=1\).
我们分块,每次修改暴力修改一个块,求出 \(x\),使得 \(\le x\) 的带入是 \(a\),\(>x\) 的带入是 \(a+1\).
这个 \(x\) 可以从 \(a+1\) 倒推回来。
最后暴力把所有块的答案算起来。当然,可以把所有块用线段树维护。
CF1948F
我们对于每个询问,也就是两部分,分别有 \(x,y\) 个银币,使一边比另一边至少多 \(k\) 的概率。
枚举差 \(\dfrac{1}{2^{m}}\sum_{c\ge k}\sum_{d\ge 0}C_y^dC_x^{d+c}\).
范德蒙德恒等式:原式 \(=\sum_{c\ge k}\sum_{d \ge 0} C_y^{y-d} C_x^{d+c}=\sum_{c\ge k}C_{x+y}^{y+c}\).
因为 \(m=x+y\) 为定值,所以我们预处理前缀和即可。
CF1967C
首先树状数组是一棵深度 \(\log n\) 的树。注意到叶子节点的值不会变。
然后我们顺势往上推,枚举子树的每个点。
若到子树的根距离为 \(d\),则贡献次数是 \(C_{d+k-1}^{d}\),类似于做前缀和,方案数是路径数。