正睿省选模拟赛

22省选10连测 Day1

赛时得分:20+30+40
订正得分:100+100+100
rk6

A. 【2022省选十连测 Day 1】01串

算法:dp FFT 容斥
相当于每次删掉一个字符,但是这样会重复。
所以我们对于一段0,我们优先删掉他们的最后一个,对于一段1,我们优先删掉他们的第一个。
这样如果在开头补一个0,末尾补一个1,我们一共有这4中操作

  • 删掉开头一个 1
  • 删掉末尾一个 0
  • 删掉一个 01 变成 0
  • 删掉一个 01 变成 1
    我们考虑 \((i,i+1)\) 中什么时候被删掉,不难发现,如果 \(s_i\) 是 0,那么 \(i+1\) 应该比 \(i\) 早删掉,这里填上一个 < 号,否则填上一个 > 号
    这个问题就变成了 loj575
    具体的做法是,我们用 \(f_i\) 表示以 \(i\) 结尾的答案,对于一段连续的小于号,我们只有唯一的选法,在大于的位置,我们考虑容斥。

\[f_i=\sum_{j<i}[s_j==>]\binom{i}{j}(-1)^{cnt_{i-1}-cnt_j}f_j \]

不难发现这个东西可以分治 FFT 优化,复杂度变成了 \(\mathcal O(n\log^2n)\)
对于 ? 的情况,直接乘上一个组合数就可以了

B. 【2022省选十连测 Day 1】做菜

算法:dp
大毒瘤题
假设我们确定了顾客和 \(a\),那么显然是应该按 \(b\) 从大到小来做
最后的答案肯定是一个 \(b_i\) 加上所有 \(b_i\) 比他大的 \(a_i\)
因此可以按 \(b_i\) 从小到大排序,用一个 dp 来解决这个东西
\(f_i=\max(f_{i-1},b_i)+a_i\)
这样的话,如果我们知道 \(a_i\),这个东西同样是可以在 \(\mathcal O(n^2)\) 的时间内去求的
\(f_{i,j}=\min(f_{i-1,j},\max(f_{i-1,j-1},b_i)+a_i)\)
考虑到某一时刻如果 \(f_{i,j}<b_i\),那么后面 \(f_{...,j}\) 是不会变化的
对于还有可能变化的部分,我们考虑他的差分 \(d_i\)
不难发现这个差分一直是单增的,即 \(f\) 是凸的
这样每次进行一个关于 \(a_i\) 的转移的时候相当于是在差分中插入了一项 \(a_i\)
同时我们发现 \(\Delta=b_i-b_{i-1}\),优先队列中前缀和 \(\leq \Delta\) 的项马上就变成 \(<b_i\) 的了
所以一次操作相当于先不停的删开头元素直到队列被删空或者 \(\Delta\) 被删完,然后再插入一个 \(a_i\)
做完之后第 \(i\) 个被弹出的就是 \(f_{...,j}\) 的最终答案
在知道 \(a_i\) 的情况下这个做法可以用一个优先队列维护 \(\mathcal O(n\log n)\) 解决
考虑对于所有的 \(a\) 的情况

我们用 \(f[i][j][l][r]\) 表示在最小花费 \(l\) 前面的有 \(i\) 个,现在优先队列在 \(x\) 前面的和为 \(j\) (包含 \(x\)),答案为 \(l\),比 \(l\) 大的最小的是 \(r\)
首先我们进行删的操作

  • \(\Delta\leq j-l,\to f[i][j-\Delta][l][r]\)
  • \(j-l<\Delta<j,\to f[i][j-\Delta][j-\Delta][r]\)
  • \(j\leq \Delta\leq j+r,\to f[i][0][0][j+r-\Delta]\)
  • \(j\leq \Delta \wedge r=\infty,\to f[i][0][0][\infty]\)
    这里在 \(\Delta>j+r\) 的时候不需要再转移的原因是当 \(l\) 被删掉之后我们就不再关心这种情况的答案了
    在后两类的时候还要顺便统计一下答案,后面的可以任选乘上一个 \(V\) 的幂即可
    然后我们进行选当前这个 \(a_x=p\)
  • \(p\leq r,\to f[i+1][j+p][\max(p,l)][r]\)
  • \(p>l,\to f[i][j][l][\min(p,r)]\)
    最后再统计一下答案即可
    总体复杂度是 \(\mathcal O(n^3V^4)\),总之就是能过。。。

C. 【2022省选十连测 Day 1】树上路径

算法:dp 随机化
想到了随机化没想到 \(k=4\) 就不太懂。。。
\(k=3\)\(\mathcal O(n^2)\) 非常简单,\(f[i][0/1/2]\) 表示 \(i\) 现在往上延伸多少的时候的最大价值
然后再一个点一次枚举子树,用 \(g[i]\) 表示现在子树中 0 和 1 的个数的差是多少
转移就是 \(\mathcal O(n^2)\)
对于 \(k=4\),就是 0 和 2 的个数的差,和 1 的个数的奇偶性
发现我们最后只关心 \(g\)\(-1,0,1\) 三个位置的值,所以我们把每个点的出边 random_shuffle 一下,每次用到的最大值就不算太多,所以这个时候取上界是 1000左右就差不多了

22省选第一轮集训 day3

赛事得分:58+25+0
订正得分:100+100+100

A. 模式串匹配

算法:dp bitset
我菜
*可以不用管,接下来的问题就是带通配符字符串匹配
考虑dp,用 \(f[i][j]\) 表示 \(S\)\(i\) 位和 \(T\)\(j\) 位匹配
如果 \(j\) 不是通配符,只能从特定的 \(i-1\) 转移过来
如果 \(j\) 是通配符,没有转移限制
不难发现可以 bitset 优化
复杂度 \(\mathcal O(\dfrac{n|S||T|}{\omega})\)

B. 追逐

算法:博弈论 dp 长链剖分
不难发现如果 \(da\leq 2db\) 显然能赢,直接输出1
否则需要任意一个连通块的直径都 \(\leq 2db\)
这样就可以 dp 了,用 \(f(u,i)\) 表示 \(u\) 子树中离远的点距离为 \(i\)
每次枚举一个新子树转移

\[f(u,i)=pf^\prime(u,i)\sum_{j=0}^{2db}f(v,j)+(1-p)(\sum_{j=0}^{\min(i-1,2db-i-1)}f^\prime(u,i)f(v,j)+\sum_{j=0}^{\min(i-1,2db-i)}f^\prime(u,j)f(v,i)) \]

不难发现因为第二维和深度有关,所以考虑长链剖分,设 \(u\) 的深度为 \(h_u\)
继承重链的时候,相当于是区间乘法和区间求和
考虑转移的时候,这个 \(f^\prime(u,j)\) 的转移是非常麻烦的,但是我们注意到,在轻链头的时候直接暴力转移复杂度依然是正确的
所以我们只需要转移最前面 \(d_v\) 个和后面 \(d_v\) 个,中间我们可以直接区间乘法
这样的话我们就可以利用线段树维护长链剖分解决了,复杂度为 \(\mathcal O(n\log n)\)

但是进一步我们可以观察到,对于 \(i>h_v\)\(2db-i>h_v\) 的部分,\(h_v<db\),也就是说子树中所有的值全部是合法的
所以中间这部分线段树上乘的一直都是1,所以我们就可以不用管他们了!
所以对于一个连通块维护一个乘法标记,就可以 \(\mathcal O(n)\) 解决了

具体的做法是,考虑按照 dfs 序作为 \(f\) 数组的下标,这样可以不用值域平移
对于 \(f[dfn[u]]\),我们维护 \(s[v]\) 表示 \(f(v,i)\) 的和
那么有 \(f[dfn[u]]=s[son[u]]\times p(u,son[u])\frac{1}{1-p(u,son[u])}\)
\(tag[u]=tag[son[u]]\times (1-p(u,son[u]))\)
最后乘上一个逆元的原因是 \(f[dfn[u]]\) 这一位不需要乘上 \((1-p(u,son[u]))\)

C. 堆

算法:dp gf
我们每一个叶子分开考虑,对于一个堆的叶子集合 \(L\),对答案的贡献是 \(2^{|L|-1}\sum_{v\in L}a_v\)
所以只需要求 \(i\) 作为叶子时所有堆的 \(2^{|L|}\) 即可
\(f(L,R)\) 表示现在有 \(L+R\) 个点,编号为 \(R\) 的节点是叶子的方案数,\(g(n)\) 表示所有大小为 \(n\) 的堆的 \(2^{|L|}\)
考虑一个 \(g(L+R)\) 的转移,他可以由 \(f(L,R-i+1)\)\(R-i+1\) 下面接上一个大小为 \(i\) 的任意的一个堆来得到,堆的值只需要满足比 \(R\) 小即可任意选择,但是此时 \(R-i+1\) 不再是叶子,因此乘上 \(\frac{1}{2}\),得到转移

\[g(L+R)=\frac{1}{2}\sum_{i=1}^{R}\binom{R-1}{i-1}f(L,R-i+1)g(i) \]

\(F_L(x)\)\(\sum \dfrac{f(L,i+1)x^i}{i!}\)(即 \(f[L]\) 的EGF的导数),\(G(x)\)\(g\) 的 EGF
那么上面这个转移方程可以写成

\[F_LG^\prime=G^{(L+1)} \]

\[f(L,R)=(R-1)![x^{R-1}]F_L(x) \]

我们想要知道的是

\[\sum f(L,n-L)=[x^n]\dfrac{2}{G^\prime(x)}\sum_{L=0}^{n-1}(n-L-1)!x^{L+1}G^{(L+1)}(x) \]

注意到 \(x^{L+1}G^{(L+1)}(x)\) 实际上是 \([x^i]G(x)\) 乘上 \(i^{\underline{L+1}}\)
因此后面那一坨的 \(x^n\) 系数应该是

\[[x^i]G(x)\sum_{L=0}^{n-1}(n-L-1)!i^{\underline{L+1}} \]

拆开下降幂,发现是一个差卷积的形式,直接卷
这样如果知道 \(G\) 求出答案是容易的
下面如何求 \(g\)
注意到 \(g\) 有转移方程 \(g[n]=\frac{1}{2}\sum_{i=0}^{n-1}\binom{n-1}{i}g[i]g[n-i-1]\)
\(G\)

\[G^\prime=\dfrac{1}{2}G^2+\dfrac{3}{2} \]

这是一个微分方程,移项可得

\[\dfrac{2\mathrm d G}{G^2+3}=\mathrm d x \]

两遍同时积分可得

\[\dfrac{2\arctan(G/\sqrt 3)}{\sqrt 3}=x+C \]

也就是

\[G=\sqrt 3\tan(\dfrac{\sqrt 3}{2}+C) \]

带入 \(G(0)=1\) 可得 \(C=\frac{\pi}{6}\)
写成 \(\sin / \cos\) 的形式上下同时泰勒展开再多项式求逆即可求的 \(G\)
虽然有根号,但是泰勒展开之后恰好是没有根号的
\(\mathcal O(n\log n)\)

posted @ 2022-01-05 21:40  YuukiYumesaki  阅读(483)  评论(0)    收藏  举报