do_while_true

一言(ヒトコト)

2024.1 ~ 等我走遍了所有国度 等你终肯舍得回眸

1. LOJ6405 「ICPC World Finals 2018」征服世界

咋感觉不说原始咋建图的全是胡言乱语/qd 学习了一下这个

先强制每个 \(b\) 都和 \(inf-dep_i\) 匹配,问题中匹配的权值转化为 \(dep_x+dep_y-2dep_{lca}-inf\),这样子最小费用循环流能够强制每个点都能进行匹配。拆点进行建图:

  • \(in_x\to out_x\) 费用 \(-2dep_x\),容量 \(+\infty\)
  • \(in_x\to in_p\),其中 \(p\)\(x\) 的所有祖先,费用为 \(0\),容量 \(\infty\)
  • \(out_p\to in_x\),其中 \(p\)\(x\) 的所有祖先(包括自己),费用为 \(0\),容量为 \(\infty\)
  • \(S\to in_x\) 费用为 \(dep_x\) 容量为 \(a_x\)
  • \(in_x\to S\) 费用为 \(dep_x-\infty\) 容量为 \(b_x\)

有了建模之后模拟费用流就可以解释了。两个堆分别存的是子树到达自己 \(in\) 的路径权值,以及 \(out\) 到达子树的路径权值。退流也能变为这种的形式。

Code

2. CF1392I Kevin and Grid

平面图欧拉定理:\(C+1=V-E+F\)\(V,E,F,C\) 为点数边数面数连通块数。假设没有碰到边界的连通块数分别为 \(T_1,T_2\),那么答案就是 \(C_1+T_1-C_2-T_2\),还有就是注意到每个 \(T_1\) 一定被一个 \(F_2\) 所包围,而唯一不会包含 \(T_1\)\(F_2\) 就是四个点连通的一个面。假设四连通块个数为 \(S_1,S_2\),也就是 \(T_1+S_2=F_2\),那么就可以化简式子:

\((V_1-E_1+F_1)+(F_2-S_2)-(V_2-E_2+F_2)-(F_1-S_1)=(V_1-V_2)-(E_1-E_2)+(S_1-S_2)\)

统计各自的点数,边数,以及四点连通面个数。算点数就是 \(a_i+b_j\geq x\) 个数是卷积。边数就是 \(\min(a_i,a_{io+1})+b_j\geq x\),四点连通面数就是 \(\min_{a_i,a_{i+1}}+\min_{b_j,b_{j+1}}\geq x\)。反过来的也同理。

补:\(T_1\) 一定被一个 \(F_2\) 包围是需要题目里的限制的。只需证明不存在以下形状,从而在边角上的 \(F_2\) 不会断开。

     a[1]  a[2]
b[1]   1    0
b[2]   0    1

列出不等式相加发现 \(a_1+a_2+b_1+b_2\)\(\geq 2x\)\(<2x\),矛盾。

Code

3. gcd 矩阵行列式

\(C_{i,j}=\gcd(i,j)\)\(\det C\),首先欧拉反演得到 \(C_{a,b}=\sum_{i|a,b}\varphi(i)\),尝试将矩阵 \(C\) 分解,写成 \([i|a][i|b]\varphi(i)\) 发现可以构造 \(A_{a,i}=[i|a]\varphi(i),B_{i,b}=[i|b]\),那么 \(C=AB\Rightarrow \det C=\det A\det B\)。而 \(A,B\) 均为三角矩阵,行列式分别为 \(\prod \varphi(i),1\)。所以 \(\det C=\varphi(1)\varphi(2)\cdots\varphi(n)\)

4. 愚蠢的在线法官

做法一:

先看 \(A_i=i\) 咋做。枚举排列 \(p\),然后 \((-1)^{N(p)}\prod v_{LCA(i,p_i)}\) 贡献到答案里。和树有关的排列问题套路是设 \(f_{i,j}\) 表示 \(i\) 的子树中有 \(j\) 个位置还没有确定的权值总和(它们之间的权值任意排 不代表不计算它们的权值)。初始化时 \(p_i=i\),分为自己已经确定和还未确定。

注意到 \(j\geq 2\) 时,swap 两个 \(j\) 中的 \(a_x,a_y\),得到权值相同(因为 LCA 和这两个点没关系 只和 \(i\) 有关系)且正负相反的两个方案。所以 \(j\geq 2\)\(f_{i,j}=0\)

那么仅考虑 \(f_{u,0/1},f_{v,0/1}\) 之间的合并,首先卷起来得到 \(g_{0,1,2}\),其中 \(0,1\) 不能再做啥操作直接贡献给 \(f'_{u,0}\),对于 \(2\) 存在两种方式,swap 并且两个都确定下来,swap 并且只确定一个,分别贡献给 \(f'_{u,0},f'_{u,1}\)

对于一般的情况也是一样做,如果出现了两个相同的 \(A\) 答案肯定为 0,然后只对出现了的 \(x\) 进行 \(p_x=x\) 的初始化就行。

Code

做法二:

\(A\) 按 dfs 排序之后 det 不变,因为 swap \(A_i,A_j\) 相当于同时交换两行两列。此时考虑树上差分之后,一个点相当于要对矩阵进行一个矩形加,考虑矩阵的二维差分行列式不变(二维差分线性变换矩阵行列式为二维前缀和线性变换矩阵的倒数,均为 1),转化成四个单点加 B[l][l]++,B[r+1][r+1]++,B[l][r+1]--,B[r+1][l]--

从而联想到这是基尔霍夫矩阵,去掉 \(k+1\)\(k+1\) 列求行列式,相当于连边 \(l\to r+1\),求生成树个数。由于 dfs 序区间两两不交,肯定不存在同胚于 \(K_4\) 的子图,广义串并联图方法即可。

5. P5548 [BJ United Round #3] 押韵 / LOJ 6696 复读机 加强版

这里推的时候用 P5548 [BJ United Round #3] 押韵 的 \(n,k,d\)

\[[x^{nd}]\left(\sum_{i=0}\frac{x^{id}}{(id)!}\right)^k \]

\(\sum\limits_{i=0}[d|i]\frac{x^i}{i!}\) 单位根反演推一下是 \(\frac{1}{d}\sum\limits_{i=0}^{d-1}e^{w^ix}\)\(w\)\(d\) 次单位根。那么所求答案就是

\[\frac{1}{d^k}[x^{nd}]\left(\sum_{i=0}^{d-1}e^{w^ix}\right)^k \]

尝试把里面那个展开,考虑 \(d=6\) 时用 \(e^A=e^{w^0x},e^B=e^{w^1x}\) 表示所有的 \(e^{w^k}\)\(e^A,e^B,e^{B-A},e^{-A},e^{-B},e^{A-B}\),还元 \(y=e^A,z=e^B\),那么展开后的每一项都能表示成 \(y^iz^j=e^{(i+jw)x}\),从而转化成求 \(k^2\) 次快速幂。

(为了方便后面用 \(x,y\) 代替原来的 \(y,z\)

那么现在就是算 \((x+y+x^{-1}y+x^{-1}+y^{-1}+xy^{-1})^k\),D-Finite,是个二维的整式递推,手算一下:令其为 \(G(x,y)=F(x,y)^k\),对 \(x\) 求偏导:

\[\frac{\partial}{\partial x}G(x,y)=kF(x,y)^{k-1}(1-x^{-2}y-x^{-2}+y^{-1}) \\ F(x,y)\frac{\partial}{\partial x}G(x,y)=kG(x,y)(1-x^{-2}y-x^{-2}+y^{-1}) \]

\(g_n\)\([x^n]G(x,y)\) 是一个关于 \(y\) 的多项式,上式两边提取 \([x^n]\) 那么有:

\[(1+y^{-1})g'_{n-1}+(y+y^{-1})g'_n+(y+1)g'_{n+1}=k(1+y^{-1})g_n-k(1+y)g_{n+2} \\ n(1+y^{-1})g_{n}+(n+1)(y+y^{-1})g_{n+1}+(n+2)(y+1)g_{n+2}=k(1+y^{-1})g_n-k(1+y)g_{n+2} \\ (n-k)(1+y^{-1})g_{n}+(n+1)(y+y^{-1})g_{n+1}+(n+2+k)(y+1)g_{n+2}=0 \]

换元 \(n\leq n+2\) 就得到比较好看的递推式了。先二项式定理展开得 \(g_{-k}\) 再逐个递推即可。

\(d=3,4\) 也是一样推,\(d=2\) 直接二项式定理展开,\(d=1\) 就是 \(k^n\)

Code

6. 「2021 集训队互测」抽奖机

\(n\) 维,每维度大小为 3 的多项式(\(n\) 位三进制数)描述问题。对于状态 \(S\) 其系数 \(F_{S}=\sum\limits_{i=1}^m[x=a_i\wedge y=b_i]\)。那么 \(F^k\) 即为答案,其中乘法为对应位上长度为 3 的循环卷积。

对于高维循环卷积的形式,我们知道实际上就是对每一维度单独作 dft 就是这个高维的 dft,也就是每一位贡献系数的乘积就是总的系数(仿照 fwt 理解,其实就是张量积)。知道 \(S\to T\) 的贡献系数实际上就是 \(\prod\limits_{i=1}^n w_3^{S_iT_i}\)。而其逆变换就是正变换贡献系数取倒数,最后再乘 \(\frac{1}{3^n}\)

\(a,b\) 为 1,2 的数量。\(a,b\) 相同,那么 \(F\)\(dft(F)\) 也相同。那就尝试怎样通过 \(G_{a,b}\) 得到 dft 后的 \(G_{c,d}\)。这里 \(G_{a,b}\) 指的是 1,2 数量为 \(a,b\)\(F\) 个数,后者是 1,2 数量为 \(a,b\)\(dft(F)\) 的值。

考虑最终的每个 0,1,2 初始都是啥,容易列出来贡献系数是 \([x^ay^b](1+x+y)^{n-c-d}(1+wx+w^2y)^c(1+w^2x+wy)^d\)

枚举 \(c,d\),那么每次就是乘除一个简单多项式,可以做到单次 \(\mathcal{O}(n^2)\),这样总的复杂度就是 \(\mathcal{O}(n^4)\)

卡常/fn Code

7. 分层图

考虑类似插头 dp,\(f_{x,i}\) 表示考虑完了前 \(x\) 层,在第 \(x\) 层上有 \(i\) 对插头往下延伸。列出转移矩阵之后矩阵快速幂就行了。这里需要注意的地方是单点必须和某个东西连起来。考虑 \(i\)\(j\) 的贡献,枚举有 \(k\) 对插头是不接在一起的,那么剩下的 \((i-k)\) 对插头就和单点一样必须和其它的连在一起,这样方案数就很好用组合数算了。另一个思路是钦定有 \(k\) 个单点是单独的,去容斥。总之都是三方算一下贡献系数然后矩阵快速幂。

Code

8. 《关于因为与去年互测zjk撞题而不得不改题这回事》

考虑暴力在 Trie 上咋做。往下递归的时候先看 1 子树 size 是否 \(\geq m\),如果是的话往右递归,否则往左递归,并且把右子树中的 \(<m\) 个插到左子树中。这样就发现其实只有最大的 \(m\log V\) 个有用。考虑每次找出下一个第 ? 大的东西,那就是超级钢琴,重链剖分搞个 ST 表,初始把 log 个重链 push 到堆里面,每次取出一个之后再把最大值两侧的区间 push 进去。

另一个实现是卡卡空间搞个树上主席树。另另一个实现是线段树套链表,按照权值插入,将 \(dfn_i\) 到线段树根上所有节点的链表都 insert 当前权值,查的时候就重剖把 log^2 个链表拉出来,再拿个堆维护表头实现归并就行。

Code

9. ucup 2 Jinan H Basic Substring Structure

分类讨论一下 Zbox 和 \([1,z_i]\) 是否有交,然后再讨论它对每个位置答案的贡献是啥。只会对 \(z_i+1\)\(i+z_i\) 这两个位置有一个《如果改成字符 \(c\) 那么答案会多 \(v\)》的一个贡献。实现上有好多细节/zk

Code

10. ucup 2 Jinan G Gifts from Knowledge

扩展域并查集判无解,答案是 \(2\) 的连通块个数次方。Code

11. ucup 2 Jinan K Rainbow Subarray

对顶堆,拿俩 set 更好写。Code

根据原根的定义,如果 \(g\)\(n\) 的原根,除了满足 \(g^{\varphi(n)}\equiv 1\) 外,还需要满足对于任意更小的 \(k\)\(g^k\ne 1\),仅需检查 \(k\)\(\varphi(n)\) 的尽可能大的因数,即 \(n/p_1,n/p_2,\cdots\) 其中 \(p\)\(n\) 的所有质因数。

12. LOJ 3067 「ROI 2016 Day2」二指禅

做这种垃圾卡常题简直就是傻白...polylog 想不明白就去想根号。首先肯定有 dp \(f_i\) 表示前 \(i\) 个字符划分的最小花费。\(\leq \sqrt L\) 的串就可以全都插到正反两个 Trie 里,往前枚举 \(\sqrt L\) 个位置填表,往后枚举 \(\sqrt L\) 个位置刷表;\(>\sqrt L\) 的串 \(t\) 与文本串 \(s\) 正反跑个 Z 把 \(s\) 每个前缀与 \(t\) 的 lcs,每个后缀与 \(t\) 的 lcp 跑出来,然后拿个树状数组优化转移就行,或者分块。

后面那部分把 lcp lcs 都存下来这里还得卡空间/流汗 不能把 <长度,权值> 的二元组 push 到对应位置的 vector 里,这样是四倍 LsqrtL 的常数,只需要把每个串 <lcp[],lcs[],w> 这样 vector vector int 的三元组存下来就行,只有三倍常数。

Code

13. HDU 6791 Tokitsukaze, CSL and Palindrome Game

歌唱一下王国,相当于比较两个回文串 border 的字典序,PAM 的 fail 上 hash 倍增一下。

Code

14. CF1483F Exam

?直接对每个串的所有前缀找到最长的后缀满足它出现过(ACAM 上倍增),然后在 fail 树的 dfs 序上搞个树状数组来处理一个串有没有子串出现过,就做完了?

Code

15. P4548 [CTSC2006] 歌唱王国

有关概率生成函数 \(F(x)\)

期望:\(E(X)=F'(1)\)\(E(X^{\underline k})=F^{(k)}(1)\)(直接按定义写就行)

方差:\(D(X)=E(X^2)-E^2(X)=E(X^{\underline 2})+E(X)-E^2(X)\)。即 \(D(X)=F''(1)+F'(1)-[F'(1)]^2\)

字符集大小为 \(m\),给定序列 \(s\) 大小为 \(L\)\(F(x)\) 为结束时长度 \(i\) 的概率的生成函数,\(G(x)\) 为长度为 \(i\) 是还未结束的概率的生成函数。\(a_i\)\([1,a_i]\) 是否为一个 border。

列一下式子:

  • \(F(x)+G(x)=1+G(x)x\):再填一个字符有可能结束也有可能没结束,那么 \(F(x)+G(x)\) 都整体往前位移一位就是 \(G(x)\)
  • \(G(x)(\frac{1}{m}x)^L=\sum\limits_{i=1}^La_iF(x)(\frac{1}{m}x)^{L-i}\):在任意序列后面直接拼上要唱出来的序列。但是有问题是可能会提前就结束了,此时两个 \(s\) 中间重叠的部分是个 border,那么多长那部分就是 \(L-i\)

对上式求导并代入 \(1\)\(F'(1)=G(1)\),将 \(G(1)\) 代入下式得到 \(F'(1)=\sum a_im^i\)(注意 \(F(1)=1\))。

Code

16. CF1276F Asterisk Substrings

除去 * 和 empty,剩下的分四种 *A,A*,A,A*B,前三种就统计一下本质不同子串个数。问题在于 A*B 这种怎么统计。考虑对一个等价类的 \(A\) 统一计算合法 \(B\) 的个数,发现就是所有 endpos+2 的后缀,一共有多少本质不同的前缀。按照排名排序之后,总长减去相邻两两 LCP 就是答案。拿个 set 对 endpo+2 启发式合并的同时用个 SA 算这个长度就行,时间复杂度 \(\mathcal{O}(n\log^2 n)\) 挺好写的。

后半部分用 SAM 算也行,那就是在后缀树(反串的 parent 树)的根链的并,dep 之和减去按照 dfn 排序之后相邻两两 LCA,也是可以拿个 set 启发式合并。想要改成 1log 就换成线段树合并。

Code

17. CF1393E2 Twilight and Ancient Scroll (harder version)

葡萄糖。假设要决策 \(s_x\)\(s_{x+1}\)\(f_i\) 表示 \(s_x\) 删掉的是 \(i\)\(g_j\) 表示 \(s_{x+1}\) 删掉的是 \(j\)。那么首先肯定要把所有删的可能按照字典序排序,然后双指针出每个 \(f\) 能够转移到的前缀 \(g\)。比较的话就分讨,记一下 \(nxt_i\) 表示从 \(i\) 开始往后,第一次 \(a_i,b_i\) 不相等的位置是哪个,然后中间还会有 \(\pm 1\) 的偏差所以记三个 \(nxt\)。然后就做完了... 实现上的细节可以在后面多补一些比 a 小的字符使得两字符串长度均为 \(\max(|s_x|,|s_{x+1}|)\),从而避免讨论长度的情况。时间复杂度 \(\mathcal{O}(\sum|s_i|)\)

Code

18. P5420 [CTSC2016] 香山的树

怎么是 lyndon 题/ll 完全不会啊 对着高爸来抄写一下

限定长度 \(\leq n\),字符集大小 \(26\),给定字符串 \(p\),求字典序大于等于 \(p\) 的 lyndon 串中字典序第 \(k\) 小的串。

每次计算以当前 \(p\) 为开头的 lyndon 串个数 \(k'\)

  • \(k>k'\),那么 \(p\) 一定不是答案的前缀,让 \(p\) 字典序增加 \(k'\) 即将 \(p\) 末尾连续的 z 删掉之后再讲末尾增大 1,\(k\) 减去 \(k'\)
  • \(k\leq k'\),那么 \(p\) 一定是答案串的前缀,如果 \(p\) 不是答案的话 \(k\) 减去 1,然后 \(p\) 后面添加 一个 a

一共要完成 \(\mathcal{O}(n|\Sigma|)\) 次计算,现在来看怎么计算字典序 \(\geq s\) 的 lyndon 个数。

lyndon 是循环同构意义下的字典序严格最小串,也就是它不是循环串(有整周期)同时最小表示是本身。直接数 lyndon 不好数,既然都考虑到循环同构了去考虑数环,再考虑断环为链,以每个 \(p\) 的开头断,那么一个出现了 \(c\)\(p\) 的环就被统计了 \(c\) 次,以 \(\frac{1}{c}\) 的权值统计就行。

那么现在问题就变成了数这样的字符串 \(s\) 的数量:

  • \(p\) 为开头;
  • 不是循环串;
  • 任何大小为 \(|p|\) 的子串字典序 \(\leq p\)

先不管循环串的限制。

考虑 \(s\) 重复无限次在 \(p\) 的 KMP 自动机上跑,最后一个限制相当于要求 \(s\) 失配时的字符,一定要大于不断跳 \(\text{fail}\)\(p\) 与其比较的字符。这时发现一个合法的 \(s\) 等价于一个从 \(\text{fail}_m\) 开始并结束于 \(\text{fail}_m\),且长度为 \(|s|\) 的环,于是可以设置 dp 状态 \(f_{i,j,c}\) 表示从 \(\text{fail}_m\) 开始走了 \(i\) 步,当且在自动机的 \(j\) 点,一共匹配成功了 \(c\) 次。

跳这么多次 fail 会比较很多次。但其实 \(p\) 是 lyndon 的前缀那么 \(p\) 一定是一个近似 lyndon 串 \(www...wv\),从而它的所有 border 一定是大小为 \(k|w|+|v|\) 的,也就是在跳 fail 的时候比较的是同一字符。

那么往后匹配的时候,一旦失配就会直接跳到头,或者匹配上往后走一步,一共只有两种不同的转移,总的 dp 时间复杂度就是 \(\mathcal{O}(n^3)\)

毕竟是按长度 dp 的,所以循环串的处理可以容斥掉。考虑计算出来的答案是 \(g_i\),正确的答案是 \(f_i\)。考虑用 \(f\) 拼出 \(j\),先乘 \(c\) 得到方案数,再除以 \(c\times (i/j)\) 带上权值,那么就是 \(g_i=\sum_{j|i}\frac{j}{i}f_j\)\(if_i=ig_i-\sum_{j|i,j<i}jf_j\)

具体实现上还有精度问题... 设个 inf 表示中间爆了 inf 就一定认为有关它的运算到最后会 \(>k\)

Code

19. Horrible Cycles

考虑一下插头 dp,像这种前缀连边的套路是对左右部点以适当的方式排序使得一个左部点连的右部点都在其前面。dp 记录前 \(i\) 个点有 \(j\) 条有向链的方案数 \(f_{i,j}\),如果是右部点分为在环中和不在环中 \(f_{i,j}=f_{i-1,j}+f_{i-1,j-1}\);如果是左部点 可以选择两条链合并,\(f_{i,j}=f_{i-1,j}+f_{i-1,j+1}\cdot(j+1)\cdot j\)

对于每个左部点来说 \(f_{i,1}\) 将一条链首尾相接得到一个环。最后减去所有二元环再除以 2 得到答案就行(一个环被正反记了两次)

Code

20. Preserve Diameter

首先直径两端点的这个二元组唯一,要不然总可以加入一条边使得直径不会变短(将某个端点连向距离它为 2 的点),那么现在直径端点 \((x,y)\) 唯一,以 \(x\) 为起点考察 \(dis\),发现 \(dis\) 相同与相邻的点之间一定有连边(连上之后 \(dis\) 与直径都不会发生改变)并且 \(\Delta dis>1\) 的一定不会连边。所以确定 \(dis\) 后就确定了一张唯一的合法的图。

虽然我们不知道直径在哪儿,但原树直径的中点 \(dis\) 一定为 \(len/2\)\(len\) 为直径长度)。所以可以以原树直径中点为根,以它作为 \(dis\) 的零势点,那么树边每一条可以是 \(+1,-1,0\) 表示两端点 \(dis\) 的差值。那么 \(f[x][0\sim 2][0\sim 2]\) 表示 \(x\) 为根的子树内,有 \(0,1,\geq 2\) 个是 \(+len/2\)\(0,1,\geq 2\)\(-len/2\),方案数是多少。

注记:如果直径中点是条边就以两端点分别为根 dp 一下然后再合并;直径端点二元组唯一的性质是保证 dp 的复杂度的。

Code

21. CF1264D2 Beautiful Bracket Sequence (hard version)

对于一个确定的括号序列答案是 \(\max\{\min(pre_{i-1},suf_i)\}\)\(i-1\) 及以前左括号数,\(i\) 及以后右括号数。然后取到 \(\max\) 的地方必有一个 \(\min\) 那里取到等,因为总可以在保证 \(\min\) 不变的前提下进行调整使得 \(\min\) 取等。

所以就考虑 \(suf_i-pre_{i-1}=0\) 的位置,然后发现 \(i\) 每增大 1 这个差值一定减少 1,所以这个位置是唯一的。枚举这个位置是 \((i,i+1)\) 中间间隔,再枚举答案为 \(k\),假设前面有 \(l\) 个左括号,\(u\) 个问号,后面有 \(r\) 个右括号,\(v\) 个问号,那么答案就是:

\[\sum_k k\binom{u}{k-l}\binom{v}{k-r} \]

化简完得

\[u\binom{u+v-1}{v+r-l-1}+l\binom{u+v}{v+r-l} \]

Code 我怎么之前写过一遍代码我还没看见?

22. CF1089I Interval-Free Permutations

对大小为 \(n\),根为析点,且根的儿子个数为 \(n\) 的析合树计数 \(f_n\)。反过来算不满足的:

根为合点:先考虑递增的合点,那么要求存在一个前缀 \(p[1,i]\)\([1,i]\) 的一个排列。令 \(g_i\) 表示长为 \(i\) 且任意一个前缀 \(p[1,j]\)\([1,j]\) 的排列,\(g_n=n!-\sum_{i=1}^{n-1}g_i(n-i)!\),枚举最靠前违反限制的前缀。所以根为合点的情况答案是 \(2\sum_{i=1}^{n-1}g_i(n-i)!\)

根为析点:假设有 \(c\) 个儿子,那么儿子排列相当于大小为 \(c\) 的子问题 \(f_c\),此时需要计算将 \(n\) 个数划分为 \(c\) 个连续段,递推 \(h_{i,j}=\sum h_{i-k,j-1}k!\) 即可(注意这里 \(c\geq 4\))。

Code

23. P7278 纯洁憧憬

这里记号沿用上个题的。先反过来算所有连续段均 \(\leq k\) 的方案数。根是析点的话是上个题的 \(f_c\) 再乘 \(t_{n,c}\),这里 \(t_{n,c}\) 是要求转移时枚举的段长均 \(\leq k\)。合点的情况,由于儿子之间的所有区间均合法,非平凡连续段就只能是 \(n\) 减去第一棵子树大小,或者减去最后一棵子树大小。那么等价于第一个段和最后一个段均 \(\geq n-k\),所以就是 \(\sum_{i,j\geq n-k}g_ig_j(n-i-j)!\)

Code

24. CF1603F October 18, 2017

\(x=0\) 的时候答案为 \(\prod_{i=0}^{n-1}(2^k-2^i)\)

\(x\neq 0\) 的时候所有 \(x\) 答案都相同。现在建立 \(x\) 合法的方案和 \(y\) 合法的方案的一组双射。线性无关组一定可以插入若干向量使得其成为线性空间中的一组基,那么找到两组基 \(S_x=\{x,\cdots\}\)\(S_y=\{y,\cdots\}\),对于 \(x\) 的某个合法方案,将每个数替换成用 \(S_x\) 线性表出它的系数(每个数变成了系数向量),将这个系数代入到 \(S_y\) 中得到一组方案。这显然是个双射。考虑如果前者不存在某个自己为 \(x\),后者也一定不存在某个子集为 \(y\),因为基中元素不能被其它元素线性表出,所以想要表出 \(x\) 那么系数必须满足只有 \(x\) 前为 1 其余均为 0。

现在只需计算 \(\frac{1}{2^k-1}\sum_{i=0}^k f(i)(2^k-2^i)\),其中 \(f(i)\) 为秩为 \(i\) 的方案数。考虑每次插入一个数后秩 \(r\) 是否改变,如果 \(r\) 不变那么系数乘上 \(2^r\),否则系数乘上 \((2^k-2^r)\)\(r\gets r+1\)

后半部分的贡献是确定的,就是 \(\prod_{j=0}^{i-1}(2^k-2^j)\),那么剩余的就是 \({n\brack i}_2\) 的组合意义了。综上,答案就是:

\[\frac{1}{2^k-1}\sum_{i=0}^k{n\brack i}_2\prod_{j=0}^{i}(2^k-2^j) \]

Code

25. CF1450H2 Multithreading (Hard Version)

好麻烦啊呜呜呜推了好久

首先考虑给定局面计算答案,每次如果有相邻同色的就可以将它们都删去,这样子就只剩下 bwbwbw...,那么答案就是剩余 \(b\) 的个数 / 2。考虑对位置进行红蓝染色之后,每次删掉的一定是异色下标的同色点,如果不存在异色下标的同色点那么环一定形如 bwbwbw...,所以答案就是 \((\) 奇数位置白色个数 \(-\) 偶数位置白色个数 \()\div 2\)

\(a\) 为白色奇减偶,\(b\) 为问号奇数个数,\(c\) 为问号偶数个数。先假设所有 \(b\) 都为白色那么 \(d=a+b\),这样对于每个问号都能选择将其染成黑色使得 \(d \gets d-1\),该方案的权值就是 \(\frac{|d|}{2}\)

注意要使 \(d\) 为偶数,那么实际上最后一个问号的颜色是确定的,所以一共有 \(2^{b+c}\) 种方案,实际答案就是:

\[\frac{1}{2^{b+c}}\sum_{i=0}^{b+c}[2|(a+b-i)]\cdot|a+b-i|\cdot \binom{b+c}{i} \]

至此已经可以通过 H1,继续化简式子,令 \(p=a+b,q=b+c\),将 \(i\) 的范围改写为 \(\leq p\)\(>p\) 从而拆掉绝对值,而 \(p\) 的奇偶性实际上是限制了 \(i\) 的奇偶性。通过吸收以及一些改写将式子化简为若干 \(\sum_{i=0}^r[2\mid i]\binom{k}{i}\) 或者 \(\sum_{i=0}^r[2\nmid i]\binom{k}{i}\) 的形式(见 Code1),\(r,k\) 的修改大小都是 \(\mathcal{O}(1)\) 的,从而可以求出每次 \(r\gets r\pm 1,k\gets k\pm 1\) 时式子值产生的变化。总的时间复杂度降为 \(\mathcal{O}(n+m)\)

Code1 Code2

26. ARC139F Many Xor Optimization Problems

考虑线性空间的标准基底(即每个主元都只有对应向量有值),答案为所有基底异或和。对于一个秩 \(k\) 计算它对答案的贡献。固定主元为 \(a_1<a_2<\cdots <a_k\),各种情况应该是等概率,也就是对第 \(i\) 个基底来说,\(a_i\) 位一定为 \(1\),再往下的位除了在 \(a\) 出现过的以外的位 0/1 是等概率的。也就是所有 \(a\) 出现概率为 \(1\),其余位出现概率为 \(1/2\),那么答案的期望就是 \(\frac{(2^{a_k+1}-1+\sum 2^{a_i})}{2}=2^{a_k}+\sum_{i=1}^k2^{a_i-1}-\frac 12\)

(这里的条件概率是说,样本空间是随机向量序列,已知主元位置为 \(a\) 的条件概率)

固定 \(a\) 之后,期望需要乘以得到这个 \(a\) 的方案数贡献到答案里。计算这两个的方案数:

  • 原序列中每个向量主元位置上的具体取值;
  • 基底中所有非主元位置的取值。

就是通过每个向量主元位置上的取值,将对应基底相异或就能得到这个向量。

前者是长为 \(n\)\(\mathbb F_2^k\) 向量序列秩为 \(k\) 的方案数,行秩等于列秩所以转置一下就是 \(k\)\(\mathbb F_2^n\) 两两线性无关的方案数,是 \(\prod_{i=0}^{k-1}(2^n-2^i)\)。后者就是 \(\prod_{i=1}^{k}2^{a_i-(i-1)}\)

先把常数 \(\prod_{i=0}^{k-1}(2^n-2^i)2^{-\binom{k}{2}}\) 提出来,现在就看期望 \(\times \prod_{i=1}^k2^{a_i}\) 咋算,把期望拆成三部分计算。

\(-\frac{1}{2}\):相当于要计算 \([x^k]\prod_{i=0}^{m-1}(1+2^ix)=2^{\binom{k}{2}}{m\brack k}_2\)

\(\sum_{i=1}^k 2^{a_i}\):考虑用 \((2^m-1)\) 减去没在 \(a\) 中出现的 \(2^j\),相当于考虑 \(a\) 再选上一个额外的数,然后 \(k\) 就有 \((k+1)\) 种选法,所以这部分的方案数是 \((2^m-1)2^{\binom{k}{2}}{m\brack k}_2-(k+1)2^{\binom{k+1}{2}}{m\brack k+1}_2\)

\(2^{a_k}\):枚举 \(i=a_k\) 就是 \(\sum_{i=k-1}^{m-1}2^{2i}2^{\binom{k-1}{2}}{i\brack k-1}_2\)

所以答案就是(稍微化简了一下):

\[\sum_{k=0}^{\min(n,m)}\left(\prod_{i=0}^{k-1}(2^n-2^i)\right)\left((2^{m-1}-1){m\brack k}_2-(k+1)2^{k-1}{m\brack k+1}_2+2^{-k+1}\sum_{i=k-1}^{m-1}2^{2i}{i\brack k-1}_2\right) \]

最右边的 \(\sum_{i=k-1}^{m-1}2^{2i}{i\brack k-1}_2\)\(2^{2i}\) 写成 \((2^{i+1}-1)2^{i-1}+2^{i-1}\) 两部分,然后把 \((2^{i+1}-1)\) 吸收进去,得到个 \((2^k-1)\sum_{i=k-1}^{m-1}2^{i-1}{i+1\brack k}+\sum_{i=k-1}^{m-1}2^{i-1}{i\brack k-1}_2\),上指标求和就得到了 \((2^{2k-2}-2^{k-2}){m+1\brack k+1}_2+2^{k-2}{m\brack k}_2\)

稍微化简一下(不化简也行 已经可以算了)答案就是:

\[\frac{1}{2}\sum_{k=0}^{\min(n,m)}\left(\prod_{i=0}^{k-1}(2^n-2^i)\right)\left((2^m-1){m\brack k}_2-(k+1)2^k{m\brack k+1}_2+(2^k-1){m+1\brack k+1}_2\right) \]

直接算就是线性的。

27. P4566 [CTSC2018] 青蕈领主

看我们 AppleBlue17 老师的题解就够了。加点注释:

求出形如 1 1 ... 1 n+1 问题的答案 \(f_n\),答案的计算就是 \(ans_x=f[|son_x|]\prod_{v\in son_x}ans_v\)。最后一步需要知道 \(r_0,r_1\) 的值,对 \(G(R(x))=x\) 提取 \([x^0]\) 得到 \(r_0=0\),再提取 \([x^1]\) 得到 \(r_1=1\)

然后发现自己不会半在线卷积的正确姿势,这种递推就考虑 \([l,mid]\times [1,r-l]\to [mid+1,r]\) 只有在 \(l=1\) 的情况会出现问题,也就是 \(l=1\)\([mid+1,r-l]\) 实际上还没算出来,那就先不算。再考虑修正的话就是 \(l>1\) 的时候多卷一下,具体而言就是:

  • \(l=1\)\(f[1,mid]\times g[1,mid]\to f[mid+1,r]\)
  • \(l>1\)
    • \(f[1,mid]\times g[1,r-l]\to f[mid+1,r]\)
    • \(g[1,mid]\times f[1,r-l]\to f[mid+1,r]\)

这里知道 \(g_i\) 需要提前知道 \(f[1,i]\)。正确性的理解我只会手玩一下,然后大概是找到从根往下走第一次往右拐那里开始考虑。

28. GDKOI2024 D1T3 鸡

抄的 by_chance 的做法。

\(c_i=\max\{b\}-b_i\),同时也是不删任何数的最大独立集,\(c_i>0\) 说明 \(a_i\) 一定在独立集里,所以 \(c\) 不能有相邻的都 \(>0\),同时有 \(c_i\leq a_i\)。然后考虑固定 \(c\) 之后,合法的 \(B=\max\{b\}\) 一定是一个区间。考虑固定 \(c\) 之后求出 \(B\) 的取值范围。

\(B\) 的取值是个区间我不会证。多哥说要根据构造证明 by_chance 说“不知道怎么说,我觉得挺显然的,但也不能严谨的写出来”

最小值是所有 \(c\) 加起来,构造 \(a=c\) 就行。

对于连续的一段极长 \(c_i=0\) 考虑它对 \(B\) 取值范围大小的贡献:a00000b 这样子(这里有可能没有 \(a,b\) 而是卡在序列的头尾上),首先两边的 \(0\) 不能填数(如果是卡在序列的头尾那么就能填),假设中间的有效长度是 \(x\),这 \(x\)\(0\) 都填 \(m\) 就行,但是只有 \(x\) 是偶数的时候能这么填,\(x\) 是奇数这么填的话最优方案一定是 m0m0m0m0m 就寄了,所以 \(x\) 是奇数的话有一个 \(m\) 不能填。综上,这种情况的贡献是 \(\lfloor\frac{x}{2}\rfloor m\)

对于 \(c_i>0\) 理想情况是填 \(m\)\(B\) 取值范围的影响是 \(+m-c_i\),但是有的取不到这个上界。(打表?)发现只有这种情况:p0x0x...0x0q 其中 \(x<p,q\),当然这里 p00q 也可能不存在而是卡到序列两端。

假设有 \(t\)\(x\)。考虑删掉其中一个 \(x\) 之后最优解 \(p,q\) 一定会选上。否则 \(p\) 的最优解就能选择为删 \(x\) 的最优解,从而 \(b_p\geq b_x\)(这里 \(b_p,b_x\)\(p,x\) 那里的 \(b\)),从而有 \(x\geq p\),与假设矛盾。既然 \(p,q\) 一定会选上那么 \(p\) 左侧和 \(q\) 右侧的选择状态就不会变,而剩下的部分最多给答案贡献 \((t-1)m\),中间这部分对最大值的贡献就至多是 \((t-1)m+x\)。也就是这里多算了 \(m-x\)。构造合法的 \(a\) 就将中间的 0 x 0 x 0 x 0 构造为 m m m m m x 0 即可。

现在考虑统计答案,分为三部分:

先计算出 \(f_i\) 表示长度为 \(i\)\(c\) 一共有多少合法的,\(h_i=f[\max(0,i-1)]\) (也就是整体向左位移一位并且前面添 0)。\(g_i\)\(h\)\(h\)

  1. 极长 000000 段,分为卡两端边界,卡一端边界,不卡边界。直接枚举 \(len\) 算方案数,然后乘上它旁边的 \(a,b\) 有多少种方案就行。(具体看代码)
  2. \(c_i>0\),也是分三种情况,然后方案数再乘上 \(\sum_i(m-i)\) 就行。
  3. \(c_i>0\) 多算的部分,p0[x0x0x0x]0q 枚举中间的长度,也是分三种情况计算。然后要乘上 \(x,p,q\) 的方案数。

精细实现一下可以做到 \(\mathcal{O}(n)\)(甚至不带 \(m\)),第三种情况需要求一个平方和,计算 \(n(n+1)(2n+1)/6\)\(6\) 可能不存在逆元,这里判一下 \(n(n+1)/2\)\((2n+1)\) 谁是 \(3\) 的倍数就行。

需要求 \(g\)。由于 \(h\) 是个线性递推,根据递推式可得到它的生成函数是 \(H(x)=\frac{1}{-mx^2-x+1}\),那么 \(G(x)=H^2(x)=\frac{1}{m^2x^4+2mx^3-(2mx-1)x^2-2x+1}\),从而得到 \(g\) 的线性递推。

Code

29. GDKOI 2024 D2T1 不休陀螺

萌萌题,先贪心得出两个限制,总和 \(\geq 0\),以及某个值的和减去某个值的最大值 \(\geq 0\)。固定 \(r\) 第二个限制一定一个后缀的 \(l\) 满足,二分出这个后缀然后二维数点就行。Code

30. GDKOI 2024 D2T2 计算

嗨呀 这不是我们 EI 队长的营业日志具体推法Code

31. GDKOI 2024 D2T3 染色

跑了个暴力发现矩阵满秩/jy 考虑构造单点的答案,构造看这里,但是我的实现大概是不断求 \(A_x[i][j]\) 表示需要操作长为 \(2^x\) 的十字的位置是 \((i,j)\)。然后从大往小推就行了。Code

32. GDKOI 2024 D1T1 匹配

网络流出来最大匹配之后调整就是在残量网络上找到一个黑边个数为 1 的环,拆点之后相当于找到 \((x,0)\)\((x,1)\) 的路径这样子。但是我写了个不断随机根 dfs 找这个环 Code

33. 2nd ucup Estonia I. Rebellious Edge

还能被这种题卡住的真菜完了啊/cf

包含那条反向边 \(u\to v\) 的咋求,从 \(v+1\) dp 一下 \(f_i\) 表示从 \(i\) 往左走(入边)出 \(v\) 且不碰到 \(v\) 的最短路即可。然后中间跨过的那些都选最短入边用个前缀和优化转移。将 \(f_u\) 加进答案就行。Code

33. 2nd ucup Estonia G. LCA Counting

观察出每增加一个点答案只会增加 1 或 2。自底向上贪心维护一个 01 串表示从这个子树取每次是增加 1 (0)还是增加 2(1)。最初叶子是 0。01 串被划分成了若干 0111... 这样的段。贪心时可以先将两棵子树的开头段合并成一个新的 011111,然后剩余的尽可能满足字典序最优来每次归并进来一个段。此时可以归纳出段长一定是不增的,所以可以直接拿个堆合并。Code

33. 2nd ucup Estonia C. Yet Another Balanced Coloring Problem

无向图欧拉回路。两棵树的叶子连边,把两棵树连到同一个根底下。如果一棵树子树中有奇数个叶子就和父亲连边。这个是考虑如果奇数个叶子说明要不然蓝多要不然红多,就得选择其一,然后它会对父亲的红蓝平衡造成影响。Code

34. LOJ 6734「2020 集训队论文」图上的游戏

1. 链

对所有点 random_shuffle 后依次插入,维护当前加入的点的相对顺序,以及每条边前方加入了多少个点。每次先二分出它应该加入到哪两个点之间,然后再将这个段内的所有边暴力 check 一下该放左还是放右。一共开销 \(\mathcal{O}(n\log n)\)

2. 树

假设已经知道它会划分成若干链,并且每条链已经知道包含哪些点和边(这里包括链顶的父边),而且链有标号满足祖先的会比子孙的编号小。那么从小到大插入每一条链维护树的形态,先在 dfs 序上二分出它应该挂在哪个点下面,再套用链的做法确定点和边的顺序。

现在问题是如何确定这个链的剖分。首先可以从全集二分删边得到一条 \(0\)\(u\) 的路径上的边有哪些。假设现在已经确定了若干个链的剖分,依次加入 \(u=1,2,3\cdots\),固定已经确定在链剖分里的边一定选,在剩下的里面二分删,得到 \(u\)\(0\) 之间新的边有哪些。

  • 如果只保留原来的点 \(0\)\(u\) 就连通,说明 \(u\) 在某个已经确定好边集的链中,在链的编号之间二分得出 \(u\) 在哪条链中。
  • 否则可以得到 \(u\) 与这个链剖分之间的若干条边,将它们设为新的链即可。这些链的边集已确定,点集还没确定,但是在后面的时候会由上一种情况问出。

3. 连通图

首先是找生成树,二分删边的方法依然可以求出 \(0\)\(u\) 的边集,所以直接套用树的做法就行。

确定好生成树之后,每次剥叶子确定叶子 \(u\) 连出去的所有非树边。先将其父边删去,然后每次二分加入一个前缀的非树边 check 这个前缀中是否有与 \(u\) 相连的非树边即可。确定好这些边之后同样在 dfs 序上二分得到每条非树边的终点。

Code

35. CF1753D The Beach

两年前被这 2400 斩于马下了 ... 做法就题解区做法。

Code

36. CF1918F Caterpillar on a Tree

零天前被这【】斩于马下了 ...

\(k=1\) 就是确定一个 dfs 序,按照这个 dfs 序走,其中可以将一次 \(dis(p_i,p_{i+1})\) 替换为 \(dep[p_{i+1}]\)。注意到 dfs 序子树包含这个性质,对于一个子树 \(x\) 而言,开头必然是 \(x\)\(x\) 的子树之间顺序无所谓,因为 \(x\) 每个儿子作为 \(p_{i+1}\) 的效果是等价的。唯一的问题是让谁在最后,去和子树外的进行匹配,看式子得知应该让 \(\max dep\) 最大的排在最后。

这样子求出 dfs 序之后将 \(dep[p_{i+1}]-dis(p_i,p_{i+1})\) 贪心取就行。代码实现上用欧拉序来代替求 dis。

Code

37. CF1918G Permutation of Given

能不能来点正常一点的题?

观察到解应该很稀松,每次往后搜两位,然后找到有循环节的规律...

Code

posted @ 2024-01-10 09:43  do_while_true  阅读(162)  评论(2编辑  收藏  举报