ZJOI2019

麻将 (Medium 4/3)

高级题。

首先考虑给定一个集合,如果判断它是否有一个子集是胡的。

考虑 dp,设 f0/1,j,k,p 表示当前是否有一对将,预留了 j{i1,i}k{i},最多可以选出 p 对不同的对子的最大面子数量,于是就可以做了。

至于原题,设 gi,t,f 表示考虑完 i 的麻将,选了 t 张牌,当前 f 的状态为 f 的方案数,然后转移就是按照 f 的转移。

但是这样的复杂度无法接受。考虑到 f 的可能的状态较少,可以构建一个自动机,状态即为 f 数组的状态,Σ={0,1,2,3,4},然后在自动机上 dp 即可。

设自动机的状态数为 S,时间复杂度为 O(n2|S|)。一般方法构建自动机的状态数在 [2×103,6×103] 之间,不过鱼大把自动机最小化了一手好像能做到 |S|=567 /jk

线段树 (Easy 3/2)

题目的意思就是求所有情况下最终 tag1 的结点个数和。

根据传统,我们在一次 Modify 操作中把所有点分为五类:

  • 会被递归到,且不再继续递归下去的点,即恰好被完全覆盖的点。
  • 会被递归到,且继续递归下去的点。
  • 不会被递归到,且被完全覆盖的点
  • 不会被递归到,但是会被下传懒标记的点。
  • 不会被递归到,也不会被下传懒标记的点。

fu 表示答案,gu 表示 1u 的路径上懒标记都为 0 的期望就可以做了。

时间复杂度 O(nlogn)

Minimax 搜索 (Medium 5/?)

不难发现我们只关注权值和 W 的相对大小关系,于是可以把 <W 的数赋为 0=W 的赋为 1>W 的赋为 2

首先考虑判定问题。我们可以随意调整集合内的权值,设 fu,l,r 表示以 u 为根的子树,最终可能的值域为 [l,r] 的集合数量,其中 0lr2,那么就可以 dp 了,时间复杂度 O(n)

考虑对于一个集合,求出最小的代价。我们只需要求出使用 k 的代价不能使答案变化的方案数 gk ,则 ansk=gkgk1

我们把上面的 dp 加上一维,设 fu,k,l,r 表示以 u 为根的子树,代价 k,最终可能的值域为 [l,r] 的方案数,那么转移的话在 k 这一维就是 max 卷积,初值再修改一下,其余按照判定的转移即可,时间复杂度 O(n(RL)),可以通过 70 分。

发现 kk+1 的时候只会改变 O(1) 个叶子的 f,使用 ddp 可以做到 O(nlog2n) 的时间复杂度,但是因为 l,r 两维有 6 种状态,所以还要带一个 36 的常数,无法通过。


考虑换一种思路。发现如果确定了代价为 k,那么调整的方案我们可以贪心地取:如果 uWlca 深度为奇数,我们就把 u 的权值减去 W,否则加上 W。我们把 1W 这条链上的所有点删掉,设 cntu 表示 u 的子树内叶子节点个数,fu 表示 u 的子树内使得 u 的权值 <W 的方案数,gu 表示使得 u 的权值 >W 的方案数。

假设当前结点的深度为奇数,那么有

{fu=vsonufvgu=2cntuvsonufv

把重儿子单独拿出来,有

gu=2cntu+(vsonu,vmsonufv)×fmsonu

这是一个 ai=b+kai+1 的形式,具有结合律,于是就可以做了。

维护轻儿子积的时候需要记录 0 的个数。

代码待补。

开关 (Hard 7/0)

真的神仙题,不知道怎么想到的。

算法一

首先把初始状态和目标状态换一下,用一个集合表示当前状态中为 1 的位置,并不妨设 pi=1

ET 表示从状态 T 到状态 状态,即目标状态的期望步数,则 E=0;对于 T,我们有

ET=1+i=1npiET{ei}

其中 表示集合的异或。

这样我们得到了 2n 个方程,直接做是 O(23n) 的。

这个方程可以手解。事实上,这个方程的解是

ET=S[|ST|1(mod 2)]w(S)

其中

w(S)=(xSpx)1

证明:显然 T= 时成立,T 时,设:

F=1+i=1npiET{i}ET=1+i=1npi(ETET{i})

我们只需证明 F=0。考虑每个非空集合 SF 的贡献:若 iS,则 pi(ETET{i})w(S) 的贡献为 pi(1)|ST|,合起来就是 (1);否则贡献为 0

所以

F=1+S(1)|ST|

容易证明,T 时有 F=0

所以上述的构造是正确的。而对于初始集合 T,我们有

|ST|=xSsx

发现 pi5×104,所以可以通过简单背包求出答案,时间复杂度 O(npi)

算法二

算法一太神了,让我们尝试从正面推导。

依然设 pi=1

考虑容斥:设 fi 表示 i 步以后恰好合法的概率,gi 表示 i 步以后合法的概率,hi 表示 i 步以后回到当前状态的概率,则有

fi=gij<ifjhij

我们设 F,G,H 表示三者的概率型生成函数,上面的等式就变成了

F(x)=G(x)F(x)(H(x)1)F(x)=G(x)H(x)

但是直接求 G,H 较为麻烦,我们发现可以求出 g,h 的指数型生成函数。具体地:

{G^(x)=12ni=1n(epix+(1)siepix)H^(x)=12ni=1n(epix+epix)

所以二者的 EGF 展开后都形如 iaieix,而对于 PGF,我们只需要把 EGF 除掉的 n! 乘回去,即

λ^(x)=aebx=aibixii!λ(x)=a1bx

所以我们可以设 G(x)=iui1ix,H(x)=ivi1ix

pi 较小,我们可以通过 dp 得出各项系数,所以我们就可以通过

F(x)=G(x)H(x)G(x)H(x)H2(x)

求出答案了。

但很遗憾——这样做是错误的。因为当 b=1 时,1bx=0,上式就没有意义了。

所以我们可以给分子分母同乘 1x,此时 G,H 均收敛,那么

G(x)=u1+i1ui(1x)1ix

G(x)=i1ui(i1)(1ix)2

于是可以得到

F(1)=i1uiv1u1vi(i1)vi2

可以直接计算了。时间复杂度 O(npi)

语言 (Easy 3/2)

果然还是第二题最可做。

发现对于固定的 u,合法的 v 构成了一棵连通子树,此处我们假设 (u,u) 也合法,考虑维护这棵连通子树。

一种方法是树剖加上扫描线那样的线段树,这样就是 O(nlog2n)

发现我们只需要把过 u 的所有链的端点按照 dfn 顺序排成一圈,两两距离和除以 2 再加上 1 就是点数,所以我们可以直接用线段树合并维护过 u 的链的端点,加上 O(1) LCA 可以把时间复杂度降至 O(nlogn)

代码也十分好写。但是数据中存在 si=ti 的情况,需要注意。

浙江省选 (Medium 3/6)

考虑 m=1 的情况,发现求一个半平面交就可以了。

考虑 m=2 的情况,此时我们要求最高排名为 2 的人,可以想到先把最高排名为 1 的人去掉,然后再求一遍半平面交,只要判断每条直线在半平面交所占的区间上是否存在一个点 x0,使得 x=x0 时排名第 2

于是我们求 m 次半平面交可以解决问题,考虑如何判定。发现一条被删掉的直线在半平面交上方肯定是一段区间,我们只需要把所有的区间求出来,差分以后排序扫一遍,就可以 O(n) 实现一次判定了。

实现时需要注意的地方:

  • 本题中 x 必须是自然数,所以在判断交点还有找 x0 的时候需要注意取整。
  • 排名的定义是使得 fj(x0)>fi(x0)j 的个数 +1,所以多条直线共点,甚至在半平面交上都只占一个点的情况也要考虑进去。
  • 其他计算几何老生常谈的问题,比如手写分数类、直线的平行等。
posted @   Scintilla06  阅读(38)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示