IOI2025集训队互测 W1

也是打上集训队互测了。

Day1(20241015)

昨天病刚好,今天状态一般,第一道题以为要把所有的询问都做出来才能得分,没有看到是以做出来的最大的 n 来统计答案的,导致搓了一个 O(n5) 的做法以为大错特错了……说明读题还是要仔细。

感觉第二题或者第三题再分析一下可能可以拿到更多的分数。例如第二题的 A 性质和第三题 op=0n5000

T1 基础 ABC 练习题

首先考虑 |S1|=|S2|=n+1 的部分分,也就是不限制 ABCBCA 的数量,那就是 AGC055D 的加强版。

我们尝试检验一个串 S 是否能够被分成 xABCyBCAnxyCAB

考虑进行一个不断循环移位的过程,例如将 S1S2S3n 变成 S=S2S3S3nS1。如果有 S1A。如果 S 有满足上述条件的匹配,那么就意味着 Sx1ABCy+1BCAnxyCAB 的方案。如果 S1BC 是类似的。

如果我们转上一圈,任何时刻 x,y,z 都没有被减少到负数,那么我们就大胆认为是有解的。而具体的构造方式,例如对于 A 来说,前 x 个用来匹配 ABC,中间 nxy 个用来匹配 CAB,最后 y 个用来匹配 BCA 即可。

prei,A/B/C 表示 S 的前 i 位中 A/B/C 的数量,那么发现只要有 {xmaxi=13n(prei,Aprei,C)ymaxi=13n(prei,Bprei,A)nxymaxi=13n(prei,Cprei,A) 即可。

这样我们就可以 O(n) 检验一个串是否存在某对 (x,y) 的构造了,我们依次记上面三个数为 A,B,C,那么现在在没有限制的时候取 x=A,y=B 即可,那么合法只需要 A+B+Cn

现在假设这个串有可以自由填入的 ?,我们枚举 (x,y) 要检验其是否满足 x=A,y=B,我们维护 fa,b,c,0/1,0/1 表示当前处理过的前缀已经有 aAbBcC 的方案数,同时检验其是否满足过 xy 了,与此同时要时刻保证 Cnxy

这个 DP 转移的复杂度是 O(n3) 的,加上枚举 x,y,复杂度就是 O(n5)

现在考虑如何加上 S1S2 的限制。考虑我们找到 x0Ay0B 的最小的 x0A,y0B,如果有解,那么就显然是这对数满足条件。所以我们仍然沿用上面的 DP,但是 fa,b,c,0/1,0/1 的后两个 0/1 的含义变成是否使得 x0,y0 一定是 AB 的最小选择了。

这样时间复杂度仍然是 O(n5) 的。

T2 基础 01? 练习题

发现这个串就是 Thue-Morse 序列,通过题解的一系列证明可以得到:

定义一个串是 TM 前缀当且仅当其实 Thue-Morse 序列的前缀,或者 Thue-Morse 序列反转之后的前缀。如果一个长度 >1 的串 S 是 Thue-Morse 序列的子串,当且仅当存在 S=A+B 使得 rev(A)B 是 TM 前缀。同时这样的 A,B 最多只有 2 对,如果是两对,也就是 S=A+B+C,那么有 |A|,|C||B|=2k

我们记 c(l,r)S[l,r] 有多少种将 ? 填成 01 的方式,使得其是 Thue-Morse 序列的一个子串。统计的方式就比较简单,用满足条件的 A,B 对,减掉所有满足条件的 A,B,C 对。如果有 ?,由于我们只关注 TM 前缀,那么我们将 ? 看作通配符即可。那么我们需要对每一个后缀找到其和 Thue-Morse 序列的最长公共前缀以及 Thue-Morse 序列反转之后的最长公共前缀;对每一个前缀同样地处理后缀。

发现这个问题可以倍增求解,记 fi,j,0/1 表示 S[i,i+2j1] 能否作为 Thue-Morse 序列(是否反转)之后的前 2j 位。

由此,上面加上和减去的统计都是对 c(l,r) 进行的矩形加操作。记 t(l,r) 表示 2i=lr[Si是 ?],那么 h(l,r)=llrrt(l,l1)c(l,r)t(r+1,r)=llrrt(1,l1)c(l,r)t(r+1,n)t(1,l1)t(r+1,n)

需要维护矩形加,矩形求 t(1,l1)c(l,r)t(r+1,n),这是可以使用扫描线然后用历史和线段树处理即可,时间复杂度 O(nlog2n+Qlogn)

T3 基础 01 练习题

发现这个过程就是一个将 B 中的 0 逐渐变成 1 的过程,所以我们可以根据题目限制得到如下的限制关系:

  • 对于每一行,Ai,j=1 的格子需要比 Ai,j=0 的格子先变成 1
  • 对于每一列,Ai,j=0 的格子需要比 Ai,j=1 的格子先变成 1

这样所有 Bi,j 变成 1 的时序的偏序关系可以建成一张有向图,而最终的答案就是这张有向图的强连通分量数。

朴素建边的数量是 O(n3) 的,所以考虑对于每一行每一列建立虚点进行优化:

  • 如果 Ai,j=1,令第 j 列的虚点向其连边,其向第 i 行的虚点连边。
  • 如果 Ai,j=0,令第 i 行的虚点向其连边,其向第 j 列的虚点连边。

发现在这种情况下,Ai,j 对应的每一个点都连入了一条边,连出了一条边,所以我们完全可以将其忽略,只看做第 i 行的虚点和第 j 列的虚点之间连边。这样我们的点数是 O(n) 的,边数是 O(n2) 的。

对于每一个强连通分量,必然是联通了一些行的虚点和列的虚点,假设其连接了 L 个行和 R 个列,那么这个强连通分量就包含 L×R 个点,那么最终答案就应当从点数量中减去 L×R1 个(这些情况至少有 L2R2)。

直接暴力计算可以获得 25 分。

那么现在的问题就变成了如何快速的确定每一个强连通分量的大小了。

发现这张图很稠密,所以我们考虑能否在不改变强连通性的情况下将其补成完全图。

对于行的两个点 i,j 的出边对应点集合 Si,Sj,如果他们之间没有包含关系,那么必然存在 xSi,xSj 以及 ySj,ySi,那么 ij 就在同一个强连通分量内了,它们之间的连边无关紧要;如果有包含关系,不妨设 SiSj,那么 j 必然存在连到 i 的链,那么我们可以从 ji 连一条边,不影响强连通性。

那么,对于所有行的虚点,我们按照它的出度 |Si| 排序,然后从大的向小的连边,这样我们就将原图补成了完全图,然后就可以使用兰道定理直接解决问题了。

这样我们可以 O(nlogn) 解决一个问题,这样可以获得 50 分。

现在我们需要考虑如何解决 op=1,也就是将列逐渐加入的情况。

发现在整个过程中,如果 |Si| 在某个时刻大于等于 |Sj|,我们就可以认为存在从 ij 的连边。那么我们只需要关注第一次 |Si||Sj| 时的相对大小,那么就可以将所有的行节点初始化成一条链,然后每当加入一个列虚点的时候,找到其连出的最靠前的点和连入的最靠后的点,这两个点在链上构成的区间就会被缩成一个强连通分量。这个合并的过程可以使用并查集实现。

那么问题就在于初始化行的顺序了。发现就是将每一行按照看成一个 01 串,按照字典序从小到大排序。使用线段树上二分哈希可以做到单次 O(logn) 比较,那么排序复杂度就是 O(nlog2n)

最终时间复杂度为 O(nlog2n+Qlogn)

Day2(20241019)

T2 感觉 O(nnlogn) 很能过,结果最后只卡到了 80 分,但是考后右卡了一下卡出来了。T1 写了个感觉和正解比较像的东西,但是因为是一点一点改出来的,基本上就乱七八糟了,所以最后只拿了一点分。T3 什么题啊,一点不会。

T1 生命的循环

T2 树上简单求和

记点 i 在第一颗树上的 dfn 序为 d1,i,第二棵树上的 dfn 序为 d2,i,那么我们如果把 i 对应到二维平面上的一个点 (d1,i,d2,i)。那么修改操作就是对某些行加上 k,查询操作时求某些列的和。这个问题显然是可以使用分块维护的。

使用时候将每一个修改查询变成 O(logn) 的行加或者列和,这样就可以做到 O(nnlogn) 的复杂度。如果把 dfn 序换成括号序,稍微修改一下细节,似乎就可以把操作变成对于 O(1) 个区间的操作,就可以做到 O(nn) 了。

T3 路径计数

Day3(20241020)

T1 先到了正解,但是有 O(1) 个细节感觉有问题,所以没敢写。T2 T3 什么题啊,不会做。

T1 环上排序信息最优分割

n 个序列拼成一个环,那么相当于我们要在环上的 n 段中各切一个位置,然后求代价。我们记第 i 个断的位置在区间 [li,ri] 中。

我们在第一个区间内枚举 x1,然后进行如下 DP,fj 表示某一个分割的位置在 j 的前缀最小代价,那么对于 x[li,ri],我们有转移 fx=minx[li1,ri1](fx+val(x,x1))。其中 val(l,r) 表示选择环上 [l,r] 内元素构成的序列的代价。

发现代价不好快速查询,但是是可以直接使用数据结构做到 O(logn) 的指针移动的,所以我们可以把所有需要的 val 求出来。那么直接暴力 DP 就可以做到单次 O(n2logn)

不难发现 val 函数是满足四边形不等式的,所以我们可以使用分治优化 DP 转移,而在分治优化转移的过程中,所有需要用来转移的 val 也是较为连续的,也就是可以通过快速的指针移动来遍历所有的值,这样单次可以做到 O(nlog2n)

对于某一个选择的 x1,其会有对应的最优决策点 x2,x3xn。然后我们发现,x2,x3xn 是关于 x1 单调的,所以我们可以再套上一层分治,记对于 x1[L,R],找到每一个 xi 对应的区间,我们对 x1=L+R2 再这些范围内求解一下答案,然后就可以分治到左右两边了。为了保证复杂度的正确性,我们要让第一个序列变成所有序列中最短的那一个。

这样可以做到 O(nlog3n)。发现如果只支持删除和撤销,那么就可以做到 O(1),那么复杂度就优化到 O(nlog2n)

T2 研心

T3 无限地狱

通过题目的证明,我们得到如下结论

我们将三个集合的按照最小元素的大小从小到大依次排序为 A,B,C。显然有 1A

通过原题的一系列证明,我们可以得到如下结论:

g=gcd(c1,c2c|C|),g=gcd(b1,b2,bB)

那么有 g|gg1。同时对于 x0(modg)xA,则 yx(modg),有 yA。对于 B 同理。

现在我们讨论 f(n) 到底等于什么。

B 中的所有数都是 g 的倍数

然后讨论如果 B 种所有的数都是 g 的倍数,那么就有 gB(否则不满足 b1<c1),那么 x0(modg),有 xA

那么我们只需要保留所有 g 的倍数,然后将 A,B,C 同时除 g。只需要 A,B,C 满足条件即可。

此时 Cgcd 应为 1,同时可能 A 为空。我们记满足这种条件的方案数为 h(n)gcd=1 的限制可以用莫比乌斯反演消掉。

如果 A 为空,那么就要求 1B,那么贡献为 2n1+d=1nμ(d)×(2nd1)

其中前面的 2n1 是将 d=11C 的部分去掉,而后面的 2nd1 是处理 gcd 整除 d 的情况下 C 填入的方案(不能为空)。

如果 A 不为空,由于 B,C 此时的 gcd 应当都为 1,有 g1。所以大小关系就是 B1<C1<A1

假设 gcdd 整除,根据 g|g,那么 CA 中只能含有 d 的倍数的数,等价于将所有是 d 的倍数的数扔进去处理合法性。先不考虑 d=1 的特殊情况,我们先对一般情况进行讨论

如果 B 中不存在 d 的倍数,那么就是 AC 自由分配,由于 C1<A1,所以 d 只能在 C 中,方案数为 2nd11

如果 B 中存在 d 的倍数,那么讨论 d 是在 B 里面还是 C 里面,通过讨论可以得到三种新的可能大小顺序(B1<C1<A1C1<A1<B1C1<B1<A1)。

发现都是可能的,方案分别有 f(nd) 种。

减掉 d=1 的特殊情况,那么总共有 2f(n)(2n11)+d=1nμ(d)×[3f(nd)+(2nd11)]

综上所述,有 h(n)=2f(n)(2n1)+d=1nμ(d)×[3f(nd)+3×2nd12]

B 中存在不为 g 的倍数

根据前面的结论,xgx 会被认为是一个等价类的,同时 1A,所以分配方案共有 2d211 中方案。假设方案数为 g(n),那么转移贡献为 d=2n(2d211)g(nd)

如果 AB 均为空,方案数为 1

如果 AB 中存在一个空集的情况,枚举 gcd 整除的因子 d,那么可以任意分配这些数,但是需要减掉分配导致 AB 都是空集了,方案数为 2+2d=1nμ(d)×(2nd1)

如果 AB 均非空,如果 A 中不包含任何 d 的倍数的因子,那么所有的 d 会在 BC 中分配,同时由于 Cgcd 应当为 1,也就是 C1<B1,那么贡献为 (2nd11)

如果都包含 d 的倍数的因子,那么答案的贡献就是 6f(nd)

所以这种情况的方案数为 2f(n)(2n2)+2d=1nμ(d)×[3f(nd)+(2nd11)]

综上,有 g(n)=2f(n)(2n1)+2d=1nμ(d)×[3f(nd)+3×2nd12)]

然后 f(n)=d=2n[h(nd)+(2d211)g(nd)]

整理得:

f(n)=d=2n[h(nd)+(2d211)g(nd)]

g(n)=2f(n)(2n1)+2d=1nμ(d)×[3f(nd)+3×2nd12)]

h(n)=2f(n)(2n1)+d=1nμ(d)×[3f(nd)+3×2nd12]

我们记 S(n)=i=1nμ(i),所以 S(n)=1d=2nS(nd)

H(n)=i=0n2i2=(2n2+11)+(2n12+11)

f(n)=[l,r]p((rl+1)h(p)+((H(r)H(l1))(rl+1))g(p))

h(n)=2f(n)(2n1)+[l,r]p(S(r)S(l1))(3f(p)+3×2p12)

如果我们能够快速预处理前缀的 fh/g 了,那么就可以使用杜教筛处理这个问题了。

我们考虑 f(n)f(n1)=d=2n[(h(nd)h(n1d))+(2d211)(g(nd)g(n1d))]

发现有 f(n)=f(n1)+d|n[(h(nd)h(n1d))+(2d211)(g(nd)g(n1d))]

先抛开 h(n) 前面减掉的部分:

那么 h(n)h(n1)=d=1nμ(d)[3(f(nd)f(n1d))+3×(2nd12n1d1)]

同理 h(n)=h(n1)+d|nμ(d)[3(f(nd)f(n1d))+3×(2nd12n1d1)]

杜教筛的复杂度是 O(T(m)+nm),由于 T(m)=mlnm

所以令 m=O(n23ln23n) 取到最优复杂度,O(n23ln13n)

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