Loading

ATC

ATC 一些有价值的题

一些场上没有通过的题目都可以写,水平低也可以。主要是平时 VP 或者是刷的一些题。

ABC

ABC 313

Ex

前面思考的部分是平凡的,考虑到给定一个前排的情况如何判断是否合法。

贪心地考虑,后排的人一定是站大于前面两个人其中一个人的最小值。反过来考虑,定义一个数组 f,设 fi=min(ai1,ai)(边界同理)。那么后排要刚好大于其即可。可以把 f,b 排序,只要满足 i[1,n+1],bi>fi 即可。

说实话把上面这一部分写完之后就没写了,因为一直没有搞明白后面的 dp。

但是做了一道类似的 loj 的题之后发现原来是一个经典套路。

我们可以把题目理解成,我们要去把 ai 不断往一个有 n 个槽的序列中塞,最后弄出来 f 数组之后要满足上面那个条件。这个和 loj 那个题目有一定的相似之处,都是往一个序列中填数字,并且填的时候会有一些限制。注意到我们是取 min,我们从小到大填。

按照套路,我们记录 dpi,j 表示我们考虑前面的 i 个数字,目前形成了 j 个联通块的方案数。我们不考虑联通块之间的情况。转移有三个,新成立一个联通块,挂在某一个联通块的旁边,连接两个联通块:

  • dpi,j×(j+1)dpi+1,j+1
  • dpi,j×2jdpi+1,j
  • dpi,j×(j1)dpi+1,j1

这道题目不一样的位置是,我们转移的过程中要直接考虑限制(loj 那个题目是我们通过多记录一维来考虑限制)。

观察一下,第一种转移我们会新确定两个 f,因为我们是独立的,也就是说后面的数字和当前考虑的数字接壤取 min 一定是这个数字。由于之前已经考虑过了 i+j 个数字(对于每一个大小为 x 的联通块会确定 x+1 个数字),当前我们确定的就是 i+j+1,i+j+2,由于是递增确定的,也就是说必须要保证 ai+1<bi+j+1<bi+j+2。由于 b 排好序了,可以简单判断。

同理,如果挂在后面就是要满足 ai+1<bi+j+1,如果是连接两个是没有限制的(因为已经被之前盖住了)。

这样就可以做到非常好的转移了,最后显然是形成一个联通块。

ABC 320

F

如果只有一次是简单的,考虑两次的情况。

不妨同时记录回来的时候这个点的油量是多少,这时候就是 fi,j,k 表示在 i 位置的时候,过去的时候油量是 j,回来的时候油量是 k,最小的花费。

初始的时候 k[0,m],f0,m,k=0,之后对于每个加油站考虑其加油、回来的时候加油、不加油三种情况即可。

G

题意:

给定 n 个长度为 m 的字符串,其中只有 09 的数字。从第 0 个时刻开始,每个时刻可选择一个没有被选择过的字符串,如果一个字符串在 T 时刻固定,之后这个字符串会显示第 (Tmodm)+1 个字符。求最短在第多少个时刻之前,可以让每一个字符串都显示出数字,并且显示的数字都一样,可能无解。

n100m105

Sol:

假设固定结果数字是 num,问题可以转化成:每一个字符串可以在若干个时刻被固定,求最早的时刻能够把每个字符串都固定。

具体分析:“若干个时刻”范围是 O(nm) 的,显然最劣的情况是所有时间都叠在一起。而求最早的时刻可以考虑二分答案,之后判断是否可行即可。

这个问题显然是一个二分图匹配问题,将每个字符串看作左部点,时间点看作右部点,每次固定时间上限和数字 num 之后,可以找到字符串连接的时间节点,判断这个图是否有一个完美匹配。

然而节点数量是 O(nm),边数只会更多,行不通。考虑是否真的对于每个字符串都需要找到 O(nm) 个点。实际上不需要,因为左边只需要匹配 n 个点,因此对于每个点只需要考虑连出去的前 n 条边即可(因为这样可以保证可以找到一个之前没有用过的时刻点),因此实际上可以做到点数和边数都是 O(n2) 级别的,之后匹配即可(代码里写的是 dinic)。

ABC 321

G

技巧在于期望题要能够会转换,此题可以转化为答案为 每个联通块出现的方案数 / 总方案数。即每一个联通块对于总答案的贡献。

这下就必须考虑每个点集形成一个独立的联通块的情况数了,首先一个点集能够独立形成一个联通块(且不向外连边)的方案数存在当且仅当这个点集的红点和蓝点数量相同。

不妨设一个点集总的连边方案为 f(s),形成联通块的方案数为 g(s)。 显然 f(s) 是容易求的。而 g(s) 就是要排除掉一个点集里面存在任何一个小联通块的方案,即 g(s)=f(s)ts,tsg(t)×f(st)。注意到这时候是可能重复的,可以强制要求 t 包含 s 中的最小元素,因为注意到一旦分离出来了一个联通块,剩余的点还是会由若干个联通块组成。

之后考虑设 h(s) 表示一个集合 每个联通块出现的方案数。同理强制集合当中有最小的元素的情况下领出来一个子集,考虑其出现情况。有 h(s)=tsh(st)×g(t)+f(st)×g(t)×1

ABC 327

G

先不考虑重边,那么就是问对于每个连通块都是一个二分图的方案数。此时需要处理这样一个子问题:给定 n 个点和 m 条边有多少种有标号联通二分图的方案。

fn,m 表示 n 个点 m 条边黑白染过色(不一定要联通)的二分图个数。有

fn,m=i=0n(ni)(i(ni)m)

之后容斥可以得到 gn,m 表示黑白染过色的联通二分图个数。

gn,m=i=1n1j=0m(n1i1)gi,jfni,mj

由于这是二分染色之后的答案,所以上述子问题的答案就应该是 gn,m2

考虑枚举所有连通块的大小,那么直接背包可以求出来这一种拆分方式用 x 条边的方案数。这个 x 不会很大,因为 n 个点的二分图最多边数只有 n2×n2 种。之后对于每一个连通块需要分配点,为了避免算重可以把相同大小的连通块拿出来一起算(具体就是对于每一种大小的连通块分别枚举每一个的方案,枚举的时候钦定这一种大小的连通块分配到的最小的点在当前这个连通块中)。最后乘上这个系数即可。

如此可以算出来没有重边的情况下,用了 m 条边的满足要求图的个数。最后考虑重边,显然重边只能和 m 条边相同。相当于用恰好 m 个元素填满 M 个位置的方案数,简单二项式反演一下即可。

预处理 O(n6)。 注意到 30 的拆分方式并不多(大约 6000 种),枚举 + 背包的时候卡着连通块最多能拥有边数的上限,实际怕跑计算 4×106 不到。

ARC

ARC 167

C

神秘计数,对着官方题解瞪了好一会,主要是题目太绕了。

题意

给定一个长度为 n 的序列 Ai 和数字 k,对于所有长度为 n 的排列,考虑以下问题:

1i<jn,若 jiKij 之间建一条无向边,边权为 max(APi,APj)

对于这个无向图,求最小生成树的权值和。

问所有排列的答案和。

n5000Ai109

Sol

计算所有排列的所有答案之和,显然的想法就是单独计算每一个 Ai 其在最小生成树中出现的次数。先对 Ai 进行排序,这样我们就只需要考虑其相对顺序了。

f(x) 表示,对于所有排列 P 以下问题的答案:

1i<jn,若 jiKmax(Pi,Pj)xij 之间建一条无向边。求最多能选出来多少条边使之不能够构成任何的环。

那么对于一个 Ai 其出现次数就应该是 f(i)f(i1)。这个是好理解的,这个 f 的变化量就体现了“由于 i 的变大,新增了多少个边可以选择”,那这个东西恰恰就是 Ai 的出现次数。因此我们要求的答案就是 Ai(f(i)f(i1))

思考 f(x) 如何计算。首先我们注意到对于一个排列 P,我们并不关心其所有大于 x 的位置。因为他们一定不能够连出来边,而对于所有小于 x 的位置,我们其实也只关系其下表是多少,而不是其具体的值。这时候会发现,其实我们只关心“所有 Pix 位置的下标。

我们将这些所有的下表取出来,形成一个序列 Q。回到 jiK 的限制,贪心地思考,如果 Qi 能够向 Qi+1 连边,那么一定是最优的,因为 Q 是一个单调递增的序列。那么问题就变成了,对于所有的 Q,我们需要统计其有多少组 Qi+1QiK。再一次考虑贡献:钦定 (j,j+1) 是一个满足条件的组,那么剩下的数随便选择,唯一的限制就是不能选到 [Qj,Qj+1] 之间的数字。那么枚举间隔大小 k 即可计算。之后发现这样的组一共有 x1 组,即这个长度为 x 的序列任意两个相邻的位置都可以被钦定。这部分的答案就是

(x1)k=1K(nkx1)

可以理解成在这个值域为 n 的序列中挖掉了一块数字。

统计完所有 Q 的贡献,我们只需要在原来下标位置上所有的数都是 x 的,这部分贡献是 x! 剩下的 (nx) 个数字随便排列。因此得到

f(x)=x!×(nx)!×(x1)k=1K(nkx1)

此时就可以做到 O(nK) 计算。当然通过预处理做到 O(1) 计算 f(x)

ARC 168

C

2000 分的题,但是还是有点意思的。

这个 k 的限制很奇怪。正难则反,考虑末状态 T 能不能被 Sk 次以内做到。注意到对于这个问题我们只关心所有的形如 XY 有几种。之后贪心即可。

一共有九种转换情况。但是实际上经过一些等式建立,会发现只需要枚举 4 种就可以就出来所有别的情况了。这样可以做到 O(K4) 之后判断一下 + 组合数运算即可。

D

非常好的 dp 练习题。

注意到每一次我们其实只是需要染到至少一个白格子。同样,正难则反,考虑从最终状态转移回来。

fl,r 表示对于这个区间(且只考虑这个区间所有的覆盖方案)的最优解。转移的时候枚举这个区间最后一个选择的点 x(即最后一个从白变成黑的点)。这时候我们就要扔掉所有经过这个白点的覆盖方案(因为如果还保留下来那么这个点还是黑的),当然需要保证存在经过这个 x 的覆盖方案。这时候发现把这个区间分裂成了两个独立的 [l,x),(x,r] 的区间,这就是标准区间 dp 的形式了。

E

怎么又是正难则反!

遇到一个区间选 k 段并且求最优解要想办法往 WQS 上面靠。但是这个题并不是直接的套路,因为答案关于 k 并不是凸的。

但是经过一些手玩,我们发现一些事情。如果我们钦定了答案为 A,我们肯定是要尽量贪心地选,即选出来了目标有贡献的 A 个区间,我们想让这些区间的长度之和尽量的少。原因是我们想要尽量预留更多位置不被选择,预留越多,能够做成总区间上限越大,下线不变。

更具体地,选出有贡献的 A 个区间之后,我们首先有了 A 个区间,假设我们还剩余 nlen 个位置没有被这些有贡献的区间选进去。那么此时区间个数上限自然是 A+nlen,对于下限,注意到一个有贡献的区间加上没有贡献的区间一定还是有贡献的,所以就是 A

PS:其实上限可能取不到,但是一定不优。

观察发现,答案显然是有单调性的。那我们考虑二分这个答案,之后尝试判断这个答案是否可行。考虑判断的这个过程,这时候我们用一个相对形式化的描述,我们设一个划分出来有贡献的区间的花费是 rl 那么设 f(x) 表示答案为 x 时候最小的花费,翻译过来就是“尽量预留更多位置不被选择”。我们需要满足 f(x)nk ,原因上面已经解释过了。

会发现 f(x) 不仅仅是一个单调的函数,这还是一个下凸的函数,那么我们就可以开开心心地在上面 WQS 二分求答案恰好为 A 的时候能不能满足条件。

非常有意思的题,正难则反 + WQS 来检查二分的过程还是极为巧妙的。

F

神秘网络流知识 +1

思考没有修改的时候怎么做。吉老师线段树。你说得对,但是这个东西似乎没有太大前途,因为很难找到一个维护这样一个过程的东西。

观察到我们求的 f(x) 是所有元素的和,那么假如说没有和 0max 的过程,那么答案就是 nm2A。真正 f(x) 还应该加上每一次操作减成 <0 的元素个数,设后面这个东西为 V。思考怎么维护这个东西。考虑构造出差分数组,那么每一次操作实际上是在 Ai 处的差分 +2,之后在从左到右第一个有值的位置,也就是第一个从 0x 的位置的差分 1。原因是由于前面的 0 并没有被 1,所以这里的差分数组会缩小。而每一次操作对于 V 的贡献就应该是找到的那个第一个改变的位置。

这个东西可以用一个比较经典的 trick 来维护,注意到我们只关心下标,因此维护一个优先队列,每次插入两个 Ai 之后弹出最小值即可,答案也可以简单加上。

但是还是那个道理,优先队列这个过程有点难维护,考虑还有什么东西可以维护这样一个过程。

网络流

回想刚才优先队列的过程,可以建图:对于每个 Ai 建点,并从源点连一条容量为 2,费用为 Ai 的边,在连一条到汇点容量为 1 费用为 0 的边。最后在所有的 AiAi+1 之间连一条容量为 费用为 0 的边。跑 MCMF 得到的最小费用就是 V

对于每次更改可以模拟费用流,每次是单点修改,修改完之后先不改整体网络流向,需要判断残量网络中是否有负环。注意到只有两种 SAiAiS 的。因为只有这两条边改了,之前一定没有负环。对于第一种,要找到一个 j 满足 AjS 的费用小于 SAi,而且 AiAj 之间有流量。分类讨论,如果 j<i 那么可以维护一个线段树记录那些点之间有回流的边,之后用另一个线段树维护最小值。如果 j>i 那么之间肯定有边,取最小值即可。第二种同理。

多次转化 + tricks + 模拟费用流,让人震撼的一道题。

ARC 180

D

题意

给定序列 a,长度为 nq 次询问,每次询问一个区间。要求把这个区间划成三段,每一段的代价定义为这段区间的最大值。最小化总代价。

Sol

先观察性质,如果只划成两段,考虑最大数实在左边还是右边。发现只会有两种情况,1222 或者是 112,这两种。

考虑 3 段的时候,如果最大数载中间,那么一定是 1223,如果在左边有两种情况 1123311223。注意到后者一定不会优于 1123 或者 1223,而 1123 又可以合并到前面一种情况,因此可以不用考虑。最大值在右边和左边是一样的。

计算 1223 是好做的,考虑 11233 计算。不妨离线下来,从左到右枚举右端点,在每个位置维护 fi 表示以 i 开始 233 的结果。这个通过单调栈 + 线段树可以做到,之后由于我们认为左边有最大值,因此直接找询问区间的最大值 +minfi 即可,算出来的答案只会 最优解。最大值在右边一样。

E

题意

给定长度为 n 序列 a,满足 ai<i。对于一个长度为 n 的排列 P,定义其价值为 LIS 的长度,定义其代价为有多少个 i少于 aiPj>Pi(j<i)

对于每个 k[1,n],求价值至少为 k 的排列最小代价是多少。

n105

Sol

观察性质的 dp 题。先考虑强制代价为 0 的情况。注意到限制只和前缀的值以及相对大小有关,定义 fi,j 表示考虑到 i 位,LIS 最后一位为前 i 个第 j 大的最大价值,j 也可以定义成 j 小,转移会麻烦一点。转移有几种:

  • 新的一位不接到 LIS 后面,而且比之前 LIS 末尾要小 fi,j=fi1,j
  • 新的一位不接到 LIS 后面,而且比之前末尾要大,这个显然是不优的
  • 新的一位接到 LIS 后面,则 fi,j=fi1,k+1,kj>ai

这个 dp 问题就在于状态本身就太多了。不过观察发现对于一个下表 ifi,jfi,j+1,从 j+1 大结尾调整到 j 大结尾。这时候注意到最后一种转移 k>j 就没有意义了,也就是转移变成 fi,j=fi1,j+[j>ai]。注意到这时候 i,j 独立了,令 gi 表示全局 LIS 最后一个第 i 大的答案,有:

gi=ji[i>aj]

答案就是 maxg

之后考虑代价,消耗一次代价可以理解成对于一个点 ak0,也就是给答案 +1。考虑如果要求答案为 k,那么 ans=max(0,kmaxi=1nk+1gi)

F

题面

给定 N,A,随机生成 N 个在 [0,1] 之间的实数,将其排序,设为 0x1xN,设得到的价值为

i=1n(1+j=i+1NxjA)

求价值期望。

ARC 181

E

题面

定义一个无向简单图是好的当且仅当,存在一棵生成树 T,满足对于原图所有边 (u,v),u<v 满足在 T 中,uv 的简单路径上 u 是最小的节点且 v 是最大的节点。

给定 nm 条边的图,求 i[1,m],删掉 Ei 这条边的时候图是否是好图。

Sol

想了一会,思路基本上全错,看了题解,非常厉害的题。题解中有一部分是想到的过程,和结论没有直接关系。

下面默认 (u,v) 满足 u<v

考虑怎么样判定一个图是一个好图,困难点在于找一个生成树,还是要往熟悉的东西上面靠。生成树比较经典的东西就是最小生成树,注意到最小生成树有一个性质,如果一条边 (u,v) 不在生成树中,那么生成树中 uv 的所有边权一定小于 w(u,v)。Kruscal 就是基于这个的算法。这个性质其实和题目中的限制很像,都是关于不在树上的边与路径的关系。

通过构造来确定每一个边的边权,使得如果存在好的生成树 T,那么一定是最小生成树。一种方法是给每个点给定点权为 10i,之后 w(u,v)=10v10u。很明显所有的边权都不一样,因此最小生成树唯一。如果选择的生成树 T 不是最小生成树,那么一定存在一条边 (u,v) 不在 T 中,并且 Tuv 有一条边边权大于 w(u,v),设这条边为 (u,v),也就是 10v10u<10v10u,这种情况下一定不满足 u<u<v<v。这告诉我们,只需要检查这个最小生成树是否满足条件即可。

但是直接这样构造并不能解决原问题,因为每次要检查这个最小生成树是否满足条件,时间复杂度不能接受。能不能让构造的边权再严格一点,让得到的最小生成树满足更多的性质,来避免最后检查这个部分。抛开这个构造方法,想一些别的方案。

我们尝试满足题目一般的条件,即要求“对于原图所有边 (u,v),u<v 满足在 T 中,uv 的简单路径上 v 是最大的节点”。这个可以将边权设为 w(u,v)=(n+1)vu,首先所有边权都不一样,并且 v 小的优先级更高。这样构造出来还有一个优势就是因为是 u,那么路径上的最小值会尽可能是 u

有了这一半,自然想到另一半,即定义 w(u,v)=(n+1)(nu+1)(nv+1)。这两个拼起来按理来说就是答案,由于生成树唯一,并且在满足一半的时候会尽可能满足另一半,那么有解当且仅当这两个生成树一模一样!

先跑出来原图两个生成树 A,B,如果删除的边不在 A,B 中,不影响,否则相当于要求 usubtree(x),vsubtree(x) 并且 w(u,v) 最小的非树边。跑出来 dfn 序,相当于二维数点,因为是 3-side 的,可以用扫描线维护。

目前第二道问号题,这个构造过程真的很神仙。

ARC 182

C

题面

记一个长度为 n 的序列价值为 i=1nai 的因子个数。为所有长度 N 的值域在 [1,M] 中的序列价值之和。

N1018,M16

Sol

主要是有一个小技巧没有意识到。由于 M 很小,其中只有 6 个质数,每次填入一个数字相当于给某一些质数的指数 +1。最后价值是形如 (xi+1) 的。但是这个东西很难直接维护,这里有一步重要转化,把 (xi+1) 这个东西看做是若干堆石头,每一个里面要选择一个(或者不选)的形式。之后就可以设 dp,fi,S 表示 S 集合已经被选出来石头。矩阵乘法优化。

D

题面

定义一个序列是好的当且仅当任意两个相邻的数不相等。

给定两个值域为 [0,m) 的好序列 A,B,每一次可以对 A 的一个元素 +1modm 或者 1modm,求最少多少次能把 AB,需要判无解。

m106,n105

Sol

第一直觉就是如果 m2 一定有解。

实际上这个是对的,但是我没有想到怎么样构造方案。关键在于把 mod 去掉,这时候可以把好序列定义改成 AiAi+1,|AiAi+1|<m,这样就把取模丢掉了。最后结束的时候要求 Aimodm=Bi

注意到这样子修改对于 A 的相对大小是不会改变的(因为一个数不能穿过另一个数),也就是说,在结束的时候 A1 确定了,那么所有其它数也就确定了。这样子操作答案有一个很明显的下界,设答案数组为 C,那么下界就是 |AiCi|。能够感受到这个下界是永远可以达到的,感性理解是相对大小不变,那么只要一块移动即可(题解里面也是有详细的证明)。

注意到因为 C1modm=B1,因此 C1=B1+km,kZ。而其它的数字同样是这样的,这样相当于求 min|Ai(Bi+km)|=|(AiBi)km|。由于括号里面是定值,现在只需要考虑 km 是多少即可,初中数学就知道要去接近中位数的数,分别验证最接近中位数的两个 km 即可。

有一种 O(n) 求中位数的方法,不过这个题带一个 log 也是可以通过的。

E

提面

给定长度为 n 的序列 aK,C,M,求:

k=0K1mini=1n{(Ck+ai)modM}

其中 C,ai<M109,K109,n105

Sol

对于 minmod 比较难下手,先思考了 n=1 的时候,就是在求

k=0K1(Ck+x)modM

则:

k=0K1(Ck+x)M×k=0K1Ck+xM

右边的东西可以类欧。但是这个 min 仍然非常头大。不妨排序之后考虑先钦定所有情况都是 a1 然后考虑别的情况更优的时候贡献情况。假设 n=2,那么 a2 更优时候贡献应该是:

(Ck+a2)modM(Ck+a1)modM<0

同理拆开能够得到:

a2a1+M×(Ck+a1MCk+a2M)

注意到右边的括号里面只可能是 0/1,而又因为整体要小于 0,并且已经是排好序了,因此右边必须是 1 才可以。因此贡献就是 a2a1M。之后考虑有几次会形成更优的情况,会发现就是:

k=0K1(Ck+a1MCk+a2M)

因此两个数的答案应该是:

k=0K1(Ck+a1)M×k=0K1Ck+a1M+k=0K1(Ck+a2MCk+a1M)×(a2a1M)

同样是可以计算的。然后推广到多个数,考虑到 ai 的时候,注意到只要 aiai1 优,那么其一定是全场最优的,原因是如果 ai 要比 ai1 优,就相当于要满足:

(Ck+ai1MCk+aiM)=1

这种情况会出现当且仅当 [Ck+ai1,Ck+ai] 中间包含了一个 M 的倍数,又因为整个序列的范围在 [0,M) 之间,全体 +Ck 相当于只是向右平移了一段距离,因此整个序列只可能出现一个位置跨过了 M 的倍数,即只有这个位置的差值为 1,这也就是最优点(证明不严谨,不过可以简单通过分类讨论和作差来补充更完整的证明)。

这样就很好办了,之后的 ai 可以通过刚才类似 a2 的方法得到答案。

Si=k=0K1(Ck+aiMCk+ai1M)×(aia1M)

那么答案也就呼之欲出了,即

k=0K1(Ck+a1)M×k=0K1Ck+a1M+i=2nSi

复杂度 O(nlogn+nlogM)

F

轮到神仙题的时候了,需要转换,但是后面的数学推导也是我无法想象的。

题面

给定 NQ 次询问,每次给定 A,Bi[0,N),连一条 (i,Ai+BmodN) 的无向边,求这个连出来的图有多少个联通块。

Sol

先判掉 A=0,1 的情况。

第一步是比较反直觉的,考虑把无向图转成有向图,因为这样特殊的连边方式,就变成数有多少个环了。

Case 1:gcd(N,A)1

这种情况不一定所有点都在环里面,我们希望处理的事所有点都在环里面的情况。虽然不一定所有点都在环里面,但是一个点走至多 N 不就一定能够到一个环里面。

fN(x) 表示 xN 步能到的位置,简单计算有

fN(x)=ANx+B×AN1AnmodN

显然 {fN(x)|x[0,N)} 集合就是所有在环里面点的集合。同时还会发现 fN(x+1)fN(x)ANmodN,不妨设 d=gcd(AN,N),那么所有在环里面的点 modd 的结果都是一样的,都是 B×AN1A1modd=fN(0)modd.

考虑单独拿出来这些点,现在对他们重新编号,转化到 gcd(N,A)=1 的情况。直观的想法就是若 u=k1d+fN(0),v=k2d+fN(0),那么分别就设为 k1,k2。假如 uv,那么有:

A×(k1d+fN(0))+Bdk2+fN(0)modNdk2Adk1+(A1)fN(0)+BmodNdk2Adk1+ANBmodNk2Ak1+ANd×BmodNd

这也刻画了新的连边关系,即 (N,A,B)(Nd,AmodNd,ANd×BmodNd)。新图就是一个每个点都在环里面的图了,一方面可以从构造方法看出来,同时也可以再验证一下,因为 gcd(Nd,A)=1 那么 gcd(Nd,AmodNd) 也自然就是 1 了。

Case 2:gcd(N,A)=1

重头戏。

考虑每一个点如果在长度为 k 的环上,那么其对于答案的贡献就是 1k

假设一个点在 K 次之后走回到了自己,那么就满足:

Akx+B×Ak1A1xmodN

现在就是要找到最小成立的 k。整理一下有

(Ak1)×x(A1)+BA10modN

处理一下就是

Ak1modN(A1)gcd(x(A1)+B,N(A1))

注意这里和往常处理取模方程有点不同,因为有模数要保证是一个整数。再提取一次分子分母的公因数,令 G=gcd(A1,B),A=A1G,B=BG,那么:

Ak1modNAgcd(xA+B,NA)

同时又有,gcd(xA+B,A)=1,因为 A,B 就是互质的。因此令 N=Ngcd(N,AN) 相当于把所有 A 的因子都掏空,则

Ak1modNAgcd(xA+B,N)

把和 x 有关的东西拿出来单独分析,设 y=xA+BmodN,因为 gcd(A,N)=1,因此对于 x[0,N)y 可以恰好取遍 [0,N),而当 x[0,N) 时,每一个 [0,N) 的数字就恰好出现了 NN 次。

Sy 表示最小的 k 满足

Ak1modNAgcd(y,N)

答案就是:

NNy=0N11Sy

还可以优化,再把之和 y 有关的拿出来,令 n=gcd(y,N),那么一个 n 就会出现 φ(Nn) 次,令 Cn 表示最小的 k 满足:

Ak1modNAn

答案就是:

NNn|N1Cnφ(Nn)

最后就是计算 Cn,有性质:

  • C1φ(NA) 的因数,可以用欧拉定理得到
  • 对于 n1|N,n2|N,n1|n2Cn2|Cn1,可以直接列式证明

这样可以通过类似搜索的方法算出来 Cn

ARC 183

D

题面

给定一棵 n 个点的树,保证其存在一个完美匹配。现在要求每次删除两个叶子结点,要求树仍然存在一个完美匹配,定义这一次删除的得分为两个点的距离。重复这么做直到树被删空了,求得分之和的最大值。要求构造方案。

n2.5×105

Sol

考虑怎么样删保证仍然存在一个完美匹配,由于完美匹配的方案是固定的,定义一个边如果在完美匹配中状态为 1 否则为 0,那么要选择的路径必须是 01 交替的,可以通过归纳证明。并且一次操作之后相当于翻转所有边的状态。

给树固定一个根,两个点的距离为 depx+depy2depLCA(x,y),由于每个点都会恰好被选择一次,所以每个点的 dep 都会被计入答案中,那么想要答案尽量大就需要 depLCA 尽可能小,最希望做到的就是每一次的 LCA 都是根节点。假设根有若干个儿子,分别为 v1vk,当前 rtvc 的状态为 1,每一次操作相当于选择一个儿子 x,满足 xc,从 c,x 子树中分别选择一个点,满足两个点的路径满足条件,之后修改边的状态。显然在任意时刻只要 xc 那么一定存在一个合法路径,因此只需要考虑儿子子树大小是多少。每次选择的两个儿子子树大小都要 1,尝试贪心,每次都令 x 为满足 xc 的子树大小最大儿子,这样最后至多留下一个儿子,其他儿子的子树都会被删光。

更进一步,注意到如果根定在重心,就能够做到一个儿子都不剩,所有点都被删光,这样也就达到了理论最大值,每一次 depLCA 都是 1

最后考虑如何分别从 x,c 子树里面选择一个点,保证路径合法。注意到因为子树到根节点的路径状态确定,因此其实是两个独立的问题。考虑预处理,对于每个子树跑出所有点的 dfn 序,dfs 的过程中优先跑状态为 0 的边,会发现,如果按照 dfn 倒序的方式依次删除每一个点,可以保证从子树根到叶子结点的路径一定合法。再进行分析,会发现其到树根的路径也一定合法,而又因为 rtvxrtvc 的状态不同,也就保证了整个路径合法。

预处理 + 优先队列,时间复杂度 O(nlogn),题目很良心提前给出来初始匹配的方式,实现起来比较简单,ATC 提交记录

E

提面

给定一棵有根树和两个长度为 M 的序列 A,B 定义目前状态是好的当且仅当 i[1,m],AiBi 的祖先。初始状态保证是好的。

现在每一次可以交换两个 A 的元素,但是要保持状态是好的,求所有可能做到的序列。

Sol

先不考虑更复杂的情况,对于每个点求出来 [Li,Ri] 满足 j[Li,Ri],Ai 都是 Bj 的祖先。这个是好求的,只要保证之间所有点都在 Ai 的子树内,用 dfn 序处理。

这里所有区间有一个重要的性质,这种构造出来的区间的题目就是要观察出来的区间有什么性质,会注意到一定不存在两个相交的区间,因此所有区间会形成一个类似树的结构(当然也可能是森林)。之后从小区间往大区间考虑每一个 Ai 能够到哪里,显然 Ai 不太可能到 [Li,Ri] 的所有位置,现在希望找到一个更小的区间来确定 Ai 能够到这些位置。

定义固定点:如果一个区间 [Li,Ri] 如果其中所有点对应的区间都是在 [Li,Ri] 范围内的,那么这个区间所有点都是固定点。也就是说,这里面的所有点都不能出 [Li,Ri] 这个区间,亦也不能有点进来。也就是说 Ai 会止步于左边最近的固定点和右边最近的固定点。那么其他点一定能到达吗?答案是肯定的,如果 AiAj 那么中间经过的每个区间都至少存在一个点区间包含 [Li,Ri] 也就可以每次挤出来这个点和 Ai 交换。这里确实比较难想到可以这样定义,需要比较好的观察力。处理这个可以用颜色段均摊的思想,用 set 记录每一个区间。注意到这个区间内还有已经定好位置的数字,因此最后可选择的位置数量要减去这些数字。由于是从小到大考虑的,已经确定好的数字个数也可以得到的。

最后可能有重复数字,还需要对于每个数字除以若干个阶乘的系数。

F

题面

给定一个序列,对于这个序列可以做以下操作:

  • 每次选定一个 Al,Ar 满足 Al=Ar 而且 Al+1Al,而且 Al+1=Al+2=Ar1。把 Al+1,Al+2Ar1 都替换为 Al。代价为 rl1

求操作直到无法操作的最小代价。

n105

Sol

ATcoder 的题转化是比较特别的,这个题就是要把一个序列变化成树。

考虑按照如下的方式建树,初始建一个值为 A1 的点,从这个点开始走,如果值为 Ai+1 的相邻点存在,就走向那个点,如果本身就在值为 Ai+1 的点就不动,否则新建一个值为 Ai+1 的点,然后走过去。过程有点像建 trie。

注意到任何一个操作出来的序列都能够对应这个树上的一个路径,更进一步,因为起点和终点是固定的,因此能够找到最终无法操作路径的形式,及 sted 的简单路径,这个简单是指可以在一个点停留,但是不能重复走,因为一旦重复走必然可以再一次操作。

现在问题就变成,这个简单路径到底是什么样子能够让代价最小。先考虑一个点的代价是什么,把 rl1 的代价摊开来给每一个变化点,假设最终序列为 B,那么代价就是 dis(Ai,Bi) 即树上距离。

再一次观察,如果一个点不在 sted 的简单路径上,那么这个点一定要被缩到在简单路径上最近的点,这一部分的答案可以提前处理。这样问题就被压缩到所有点都在简单路径上的情况。

剩下的问题形如:

给定序列 A,其中 |AiAi1|1 而且 A1=1,An=maxA。要求构造序列 B 满足 B1=A1,Bn=An 而且 BiBi1 并且如果 BiBi+1,Bi=Ai,Bi+1=Ai

考虑一个 dp,令 fi 表示,确定 Ai=Bi 的情况下的最小代价。有两种转移:

  • fi1fi 这种情况要求 Ai1+1=Ai 即是一种往前走一步的情况
  • fk+j=k+1i|AiAj|fi 这种情况是这一段区间都是维持的情况,其中需要保证 Ak 是上一个满足 Ak=Ai 的位置。虽然后面有绝对值,但是因为 Ak 是上一个等于 Ai 的位置,因此中间部分都是 < 或者 >Ai 的。
posted @   Jryno1  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示