UNR #6

D1T1. 面基之路

当 hehe 蚤和网友面基成功时,网友可以跟着 hehe 蚤一起走。因此,任何面基方案必然可调整为最后一个时刻 hehe 蚤和所有网友处于同一位置的情况。

直接枚举每条边 (u,v),检查它对答案带来的贡献。设第 i 个人到 u 的最短路为 di,u,则 i(u,v) 这条边产生的贡献为左端为 di,u,右端为 di,v 的形如山峰(而非山谷)的折线 Zi,我们希望求 minx[0,wu,v]maxi=0kZi(x)

因为每条折线仅有至多一个顶点,所以 maxZiO(k) 个顶点划分成若干段,每一段形如若干斜率为 ±1 的直线的 max,最小值容易求出。

时间复杂度 O(nk2+mklogm),可以扫描线将 nk2 优化至 nklogk代码

D1T2. 机器人表演

你出的好,你出的好啊!

容易设计出状态 DP fp,i,j,k 表示当前匹配到最终串 T 的第 p 位,使用了 i0j1 且匹配到原串 S 的第 k 位的方案数。因为 p=i+j+k,状态仅有 O(nt2) 种。

考虑转移。初始想法是 贪心匹配 S,即枚举 Ti+1=0/1,若 Ti+1=Sk+1,则 kk+1,否则若 Ti+1=0i<t,则 ii+1,否则若 Ti+1=1j<i,则 jj+1

问题在于这样贪心匹配不一定最优,因为对于某个 Ti+1=0,我如果令 ii+1,就可以额外将 j 的限制放宽,放更多的 1,例如 n=t=1S=0,则上述 DP 无法统计到 T=010

考虑 反悔,即撤销 S 已经匹配的一些位置用于补充 i 使得 i>j。考场上猜的结论是对每个 k,找到最大的 q 满足 Sq+1=0(用于填补 i 的空缺),S[q+2,k] 是合法 01 串前缀,记为 lftk,则可以在 k 处撤销匹配至 lftk 处,且 S[lftk+1,k] 全部投进 01 串匹配。

不会证明,但后来发现和官方从另一种角度考虑的题解本质相同。先给出转移式,最后再说明这一点。对于 fp,i,j,k,枚举 Ti+1=0/1,则

  • Ti+1=Sk+1,转移至 fp+1,i,j,k+1
  • 否则,若 Ti+1=0,转移至 fp+1,i+1,j,k,当 i=t 时不可转移;
  • 否则 Ti+1=1,若 i>j,则转移至 fp+1,i,j+1,k
  • 否则需要撤销匹配,若 lftk 存在且 i+cnt0,kt,则转移至 fp+1,i+cnt0,k,j+cnt1,k+1,lftk,否则不可转移。其中 cnt0/1,k 表示 S[lftk+1,k] 当中 0/1 的个数。

p 滚动数组优化,i 根据 p=i+j+k 去掉,时间复杂度 O(nt2),空间复杂度 O(t2)代码

结论正确性的疑点在于:

  • 为什么 S[lftk+1,k] 全部投进 01 串匹配,而不是匹配到 S 大于 lftk 的位置?
  • 为什么 S[q+2,k] 是合法 01 串前缀?因为 S[q+2,k] 是归并插入当前 i=j 对应合法 01 串,所以似乎不需要合法。

官方题解 lftk 的定义是最大的 k<kbk<bkk,其中 b 为将 S0 看成 11 看成 1 的前缀和,然后证明了 S[lftk+1,k] 是合法 01 串前缀,且 lftkS 新的最大匹配长度,即不存在 K>lftk 使得 T[1,i+1] 可以由 S[1,K] 和合法 01 串前缀归并得到,因而说明 S[lftk+1,k] 需要全部投进 01 串匹配。

考察两种角度,显然官方题解更加严谨和完备。我的做法属于是本末倒置,瞎猫碰上死耗子恰好正确了。

D1T3. 稳健型选手

不错的猫树分治练手题。

单组询问的 O(LlogL) 解法是经典问题,类似题目有 UVA12260 Free Goodies:设 ci 表示 i 是否被选中,bi 表示 ci 的前缀和,则对于任意 i[1,L] 均有 bii2

因此,从前往后扫,每次往选中的数加入 aiai+1,但此时有 i2+1 个数被选了,需要弹出最小的选中的数,容易证明反悔贪心正确。另一种思路是从后往前扫,每次往未被选中的数加入 aiai+1,并弹出最大的未被选中的数。两种思路分别支持开头扩展和结尾扩展,因此回滚莫队可以做到 O(nnlogn),压位 Trie 可以通过。直接做的复杂度为 O(n2logn),只有 40 分

既然支持开头插入和结尾插入,但无法快速合并,容易想到 二区间合并猫树分治

考虑合并两个区间 [l,mid][mid+1,r] 时,左边没选的数必然不会重新选择,右边选择的数必然不会不选,但我们会取消选择左边一些选择的数,转而选择右边一些未选择的数。因此,维护左边选择的数集 X 和右边未选择的数集 Y,二分找到分界点,即最大的 k 使得 Xk 小的数小于 Yk 大 的数,然后将 Xk 小的数删去,Yk 大的数选上,即为答案。

主席树维护,离线询问将空间复杂度优化至 O(q+nlogn),时间复杂度 O((n+q)log2n)代码

D2T1. 小火车

非常好题目,英雄联盟,爱来自瓷器。

观察 2n>p 的限制,容易想到用 0/1 减去 0/1 得到 1/0/1。问题转化为找到两个 0n1 的子集 S,T,使得 STiSaiiTai(modp),则 bi=[iS][iT] 即为一组合法方案。根据鸽笼原理,2n 只鸽子飞进 p 个笼子,必然存在两只鸽子飞进相同笼子,故必然有解。

问题在于如何找到这样的 S,T,赛时想了一年都没有想出来:如果要恰好找到 S=T,总枚举量为 (240)2,无论如何 meet-in-the-middle 都无法减少枚举量到一个可以接受的范围。

那真的不能做了吗?当然不是。直接枚举 S,T 没有用到 2n>p 的性质,考虑利用这一性质优化算法。

fj 表示使得 f(S)=iSai=jS 的数量,问题即找出任意使得 fj2j。若存在 j[L,R] 满足 fj2,称 [L,R] 合法。

核心结论:对于任意 [L,R] 的分割方式 [L,mid][mid+1,R],必然存在至少一个区间 [L,mid][mid+1,R] 合法。

因初始区间 [0,p1] 合法,所以二分,每次将当前合法区间长度减半,logp 次后即可找到长度为 1 的合法区间。故只需求使得 f(S)[l,r]S 的数量。其相较于原问题枚举量减少了一半,总枚举量仅有 240,mitm 可以快速求解。

求得 j 后同样可 mitm 求出一组合法解,时间复杂度 O(2n/2logp)代码

D2T2. 神隐

这题出得很好,让人思维出新。

考虑最朴素的做法枚举每条边,询问次数 n1,很劣。

考虑 n 较小时的做法,n=3 时我们必须询问每一条边,换言之,对于 e1,e2,必须:

  • 存在一次询问使得 e1Ee2E
  • 存在一次询问使得 e2Ee1E

若不存在第一种询问,e2=(u,v),剩下一个点为 w,则我们无法确定 w 连向 u 还是 v

对任意 n 运用上述结论,可知还原整棵树的必要条件为对于任意相邻两条边 ei,ej,存在一次询问使得 eiEejE,存在一次询问使得 ejEeiE。因为我们不知道每条边的相邻情况,所以对于任意不同的两条边均需满足上述性质。

设第 i 条边属于集合 Si 的询问,即 Si={qeiEq},则上述性质可表述为对于任意 ijSiSjSjSi。如果构造出 E1Ek,也容易通过询问结果得到 T。将所有无序点对 (u,v) 按照它们连通的次数 cntu,v=i=1k[Ei:uv] 从大到小排序,做最大生成树即可:根据性质,非树边 (u,v) 的权值严格小于 uv 简单路径上所有边的权值。

尝试构造 n1 个两两互不包含的集合。如果限制了 X 次询问,最优方案为选择 02X1 所有 popcount=X2 的数。(147)=50401999(2010)=184756131071,可行。瓶颈在于 n2logn 的时间复杂度。

考虑利用构造出的 Si 的性质优化复杂度:每条边仅出现 X2 次。

还原树的交互题有一个非常好用的技巧:剥叶子。每个叶子恰在 X2 次询问中为孤立点,且条件充要,据此可不断剥掉 T 的叶子。

设最后一个被剥掉的节点为 R,上述过程给予我们 T 在以 R 为根时的拓扑序,考虑按拓扑序还原每个点的父亲。

x 的父亲为 fa,容易发现恰有 X2xfa 不连通,即所属连通块其它点拓扑序均在 x 之后;同时恰有 X2xfa 连通,且根据性质,x 所属连通块 C1,C2,,CX/2 的交恰好仅包含 xfa

关于树上连通块,有一个很好的性质是若干连通块相交,若交集非空,则交集深度最小的点为某连通块深度最小的点:若非,考虑交集深度最小的点 u,因其不为任何连通块深度最小的点,故 u 的父亲同样属于交集,矛盾。

因此,只需求出 C1CX/2 每个连通块深度最小的点中深度最大的那个,即为 x 的父亲。容易维护。

时间复杂度 O(nlogn)代码

D2T3. Border 的第五种求法

咕了,如果进集训队就更。

UPD:来写了。

感觉思想挺简单的,但是是未曾设想的道路。

s 建出 SAM,则 Bs[l,r] 的 border 当且仅当:

  • Bs[l,r] 的前缀。
  • B 在 link 树上是 s[1,r] 的祖先。

因为 s[l,r] 的所有前缀形成 DAWG 上一条路径,考虑 DAG 剖分将路径拆成 logn 条时间戳连续的重链,则问题转化成 O(qlogn) 次询问 s[1,r] 到根的路径上时间戳落在某区间的节点的权值和,而 i 的权值即 f|endpos(i)|

  • 如何拆重链:容易求出当前节点 i 到重链末尾形成的字符串在原串上的任意对应下标 [l,r]。不妨设当前要匹配 s[x,y],则当前重链匹配长度即 |lcp(s[l,r],s[x,y])|,容易 SA 或者 SAM 求出。

二维数点,离线后在树上扫一遍,用 BIT 维护单点修改区间查询。时间复杂度 O(nlogn+qlog2n)代码

posted @   qAlex_Weiq  阅读(1103)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示