Cry_For_theMoon  

1656

F. Parametric MST

给出 a1,a2,...,an。定义 G(x) 是这样一张完全图:对于任意两点 ij,定义其边权为 w(i,j)=aiaj+x(ai+aj)。(以下的 x 都是指实数)。

定义 f(x)G(x) 的最小生成树权值。求 f(x) 的最大值,或输出 INF 表示 f(x) 可以取到无穷大。

n2×105,|ai|106

Hint1 考虑对于确定的 x,研究 f(x) 的取值。
Hint2x 固定时,有:aiaj+x(ai+aj)=(ai+x)(aj+x)x2
Hint3 考虑 x 固定的时候,对于一个点 i 来说,所有 j 中,令 w(i,j) 取到最小值的,要么是 a 最小的,要么是 a 最大的。
Hint4 x 固定的时候,将 a 重新排序,一定是一段前缀和 an 连边,剩余的后缀和 a1 连边。
Solution

解决这类题。还是有一定套路可循的。首先我们应该研究 x 固定的时候最小生成树的构造方式,它应当足够简单,否则我们怎么能寻找 f(x) 的最大值。

考虑研究边权,固定 i,那么 aiaj+xai+xaj 中就只剩下了 aiaj+xaj=aj(ai+x) 待定。此时显然,如果 ai+x0,我们会考虑让它和 a 最大的连,这样边权是最小的;反之,如哦 ai+x0,它和 a 最小的连,边权是最小的。

如果这样连,最后确实能构成一棵树,那显然就是 mst。

方便起见,可以把 a 排序。那么 a 的一段前缀和 an 连边是最优的,剩余部分(形成一个后缀)和 a1 连边是最优的。当前缀长度 =0 或者 =n 的时候,显然就是所有边和 a1 或者 an 连(除了自己不和自己连),那显然构成的是一颗树。如果前缀长度不是 0 也不是 n。那么实质上 a1an 的连边会被算两次,把这条边的权值去掉一遍即可。

到这里我们发现 f(x) 其实可以看成一个一次函数,这个一次函数的解析式只会变化 n+1 次。每次的 x 都有一个取值范围 [L,R],然后问 f(x) 的最大值。此时一切都变得很简单了。

时间复杂度 O(nlogn),瓶颈在排序。

记录


1679

E. Typical Party in Dorm

定义 f(S) 为字符串 S 的回文子串数量。

给出一个字符串 S,有些位置已经确定,剩下位置是问号。有 q 次询问,每次询问给出一个字符集 T,求:

S 中每个问号位置填入一个 T 中的字符,问 f(S)998244353 的值。

ST 的字符集都是 {a,b,c,...,q}(前 17 个小写英文字母)的。|S|1000,q105

Hint1

考虑枚举一个子串,计算它对每个可能的 T 的贡献。

Hint2

回文建立起了两个字符的一一对应关系:我们只关注两种情况:仅一个是问号,或者两个都是问号。

对于第一种情况,设其涉及的字符集合为 C,则 CT 的时候才可能造成贡献。

对于第二种情况,设有 x 个,则其贡献应该为 |T|x

由于有 CT,考虑 fwt(高维前缀和)维护答案,现在考虑如何处理 |T|x 的影响。

Solution

注意到 |S|1000 的限制。所以我们可以暴力枚举 |S| 的每一个子串,然后计算它对答案的贡献。

那么有两种位置,中心和两侧(也可能没有中心位置)。对于两侧,即位置 xy 建立了一个对应。如果 xy 中只有一个问号,则这个问号的位置填的值是确定的,我们记作 c,这样本质自由的问号数减一。

A={c},则当且仅当给出的 T 满足 AT 的时候我们枚举的这个子串才会对 T 造成贡献。然后记本质自由问号个数为 num 则贡献为 |T|num

注意到 numA 有关,但是 |T| 是和 T 有关的。所以我们无法直接用一次高维前缀和来计算全部答案。

但是注意到 |T| 只有 17 种取值,所以当我们加入一个本质自由问号个数为 num 的子串的时候,对于每个 1i17,我们都把 f(i,A) 加上 inum。然后对每个 f(i) 进行高维前缀和。最后 f(|T|,T) 就是所求。

时间复杂度 O(n|S|2+n22n),其中 n=17。注意略有卡常。

记录


F. Formalism for Formalism

考虑所有 10n 的非负整数,位数不够则最高位补零。

给出 m 对关系 (ui,vi)。对于一个数的相邻两位 u,v,如果 (u,v)(v,u) 存在于给出的关系中,则我们可以交换它们。

A 可以通过若干次交换得到 BAB 本质相同。

问一共有多少个本质不同的数,模 998244353n5000,m45

Hint1

这类问题往往首先需要为每个等价类寻找一个代表:字典序最小就很合适。

Hint2

换言之,我们对所有不能通过交换,得到比它字典序更小的数来计数。

由于和字典序有关,所以考虑从高往低确定数字。

但我们发现,不管记录前面多少位的信息,都很难保证这个约束。

Hint3

如果一个 dp,每一步可以转移到的状态极少,考虑直接把下一步可选的内容集合压缩进状态中。

Solution

感觉挺牛逼的题。

首先我们的想法是为每个等价类找一个代表去计数。容易想到字典序最小。换言之一个数被计数当且仅当不能通过交换让它的字典序变得更小。

那么一个直接的想法是从前往后地 dp。但是我们发现记录末尾,末几位的信息都无法保证这个约束。

事实上如果我们最高位放了个 c1,那么第二位不能放 c2,当且仅当 (c1,c2) 可交换且 c1>c2。当我们放好 c2 后,同理会禁止掉一些 c3。此外,如果 c3c2 可交换,那么就算 c3>c2,如果 c3c1 禁止掉了,那 c3 也不能填入第三位。

换言之如果我们知道当前哪些数字不能填到下一位。则填完下一位后,我们可以方便地计算哪些数字不能填到下下位的。

所以直接令 f(i,S) 表示前 i 位确定,第 i+1 位不能填 S 中的数。注意到本质不同的转移只有 210×10 种,对每种预处理一下就行。

时间复杂度 O(10×210×n)。注意实现。

启示:当 dp 一步能填的状态很少的时候,可以直接记录每一步能填哪些状态来转移。

记录


1682

E. Unordered Swaps

给出一个 n 排列 p,设其通过任意交换排序的最少步数是 m。接下来给出一个长度为 m 的二元组 (x,y) 组成的序列 q。重排 q 使得按此时顺序交换 pxi,pyi 后,p 是有序的。保证存在一组合法解。

2n2×105,1mn1

Hint1

考虑排列的置换环与这个问题的联系:若要合法,则等价于每步都在拆置换环。

Hint2

研究单个置换环:如果有数对 (a,b) 则连 ab 的边,容易证明:不存在两条边在非顶点处相交。

Solution

可以vp场切 2700* 构造了,可喜可贺。

任意交换排序,是经典到不能再经典的问题了。显然 m=nk,其中 k 是置换环数量。

如果一个排序步骤花费步数是最少的,则每步都在拆环。首先对初始的 p 找出所有的置换环,显然 q 中不会有一个 (x,y) 是分属于两个置换环的。

容易发现不同置换环之间没有任何影响。所以我们考虑单个置换环上的构造。以下所有数对都属于一个置换环。

如果有两个数对 (a,b),(c,d) ,四个数两两不同,则它们谁先执行是无所谓的,放在置换环上考虑,就是说弦 ab 与弦 cd 有交,此时是不合法的:因为你不管先执行哪一个,另外一个数对一定无法执行(因为两个数分属两个置换环)。

又显然 (a,b) 不会出现多次,换言之我们只用考虑 (a,b)(a,c) 这样的数对,哪个在前哪个在后。(类似地还要考虑 (b,a),(c,a) 这样的对的顺序。)

稍微手玩后立马发现,设 f(x) 是置换环上 a 走到 x 的步数,则 (a,b) 排在 (a,c) 前当且仅当 f(b)<f(c)

所以对于所有的 (a,x) 我们按照 f(x) 排序即可。这样会构建出若干个先后的约束,连边后拓扑即可。拓扑序即为一组合法解。

至于如何求 f(x),其实只要对一个置换环上的点按顺序编个号,然后 a 和环长确定了以后 f(x) 显然是好求的。

时间复杂度 O(nlogn)

记录


F. MCMF?

给出两个长度为 n 的序列 a,b,保证 bi0。然后给出 q 次询问,每次给出一个区间 [li,ri] 且保证 likribj=0。求下列图的最小费用最大流:

rili+1 个点外带上源、汇 S,Tbi<0 的在左侧,对这样的点,Si 连一条容量为 |bi| 费用为 0 的边;bi>0 的在右侧,对这样的点,iT 连一条容量为 |bi| 费用为 0 的边。对于 bi<0,bj>0ij 连一条容量为 费用为 |aiaj| 的边。

n,q105,|bi|109,0a1a2...an109

Hint1

考虑单次询问如何处理。

Hint2

如果把 bi 认为是“有 |bi| 个物品”,则本质是寻找最小权完美匹配。

显然最优秀的匹配方式是两部分分别按照 a 排序然后对应匹配,这样就解决了一个区间的情况。

Hint3

注意到给出区间的 b=0,即一定有完美匹配。所以可以设 sufi[i...n] 这部分排序后匹配的结果,则一次询问拆成了两个 suf 相减。

现在我们可以 O(n2) 地解决这个问题了.

Hint4

对应一个位置的 (ai,bi) 来说,一定是一部分贡献为 ai,一部分贡献为 ai;而具体的长度,只取决于前面遗留了多少个未匹配点。

换言之设 S=j<ibj,其贡献和 S 相关,为分段的一次函数形式。

Hint5

当处理 sufi 的时候,(aj,bj) 就和 Sj1Si1 相关了,那么也就等价于和 Si1 相关,且为分段的一次函数形式。

所以考虑直接维护一次项系数和常数项的和。

Solution

应该是本月以来见到的最难的一道 DS 了。首先希望大家可以注意到 a 递增的限制,我眼瞎没看到这个限制浪费了一天思考时间。

q 次最小费用最大流这个东西看上去就很恐怖啊,我们把它转成些更可做的东西。套路地考虑只询问一次 [1,n] 怎么做。

首先容易发现我们肯定是左右两边各自按照 a 排序去匹配的。然后题目里 a 已经排好序了所以实质上是按照出现顺序匹配。

这样一次询问可以 O(n) 做了,难以优化,因为绝对值难以处理。

研究一个位置 (ai,bi) 的贡献,显然其一段前缀的贡献为 ai 剩余后缀的贡献为 (ai)。而这个具体的数量其实只和前面还剩下多少个未匹配的点有关。不妨设 bi<0,则令 S=k<ibk,当 S0 时,总贡献为 ai|bi|;当 0<S|bi| 时,总贡献为 2Saiai|bi|;否则总贡献为 ai|bi|bi>0 的情况有类似贡献。

另外我们设 sufia[i...n] 匹配后的结果(不要求一定能匹配完),则显然对一次询问有 ans=suflsufr+1,因为你保证了区间的 b=0,也就是说前面的对后面的匹配不造成任何影响。

所以问题变成了快速预处理 suf1n

这个时候注意到对于一对 ij(aj,bj)sufi 的贡献只和 Sj1Si1 有关,根据上面对“贡献”的研究,实际上 (aj,bj)sufi 的贡献是一个分段的函数,每一段都是关于 sufi 的一个一次函数。所以开两颗线段树(树状数组)维护一次项系数和常数项即可。时间复杂度 O(nlogn),注意要先离散化。

记录

--------

1684

F. Diverse Segments

给出一个长度为 n 的数组 a。定义 a 的一个子段 [l,r] 是好的当且仅当 alar 中元素两两不同。

现在给出 m 个子段 [li,ri]。你需要执行一次操作:选择 a 的一个区间,然后把这个区间的每个数分别替换成任意整数。要求操作完毕后给出的 m 个子段均是好的。

输出打到这个目标,操作区间的最短长度。如果不用操作,则输出 0

n,m2×105,ai109

Hint1

双指针。

Hint2

limi 是所有包含 i 的约束区间里,l 最小的那个,prei 是上次 ai 出现的位置,则合法等价于对于任意位置有 prei<limi

考虑选中一段区间,会对 pre 造成什么影响。

Hint3

pre,lim 的条件和双指针结合!

Solution

考虑把一个区间合法转成更可做的约束。设 prei 是上一个和 ai 相同的位置(没有则 prei=1),则实际上对于 i[lj,rj],应该满足 prei<lj

从一个区间变成多个区间,我们发现,对于一个 i,只要设 limi 是所有包含 i 的区间中,lj 最小的那个(没有则 limi=),则实质上题目的约束是 i,prei<limi

prelim 的求解都是经典问题,不再赘述。

把一个数任意重赋值的过程可以看作将它的 pre 置为 ,同时将 prenxti 置为 prei

另外,设 f(l) 是最小的 r 使得删去 [l,r] 合法(不存在这样的 rf(l)=)。显然 f(l) 单调不降。换言之可以考虑双指针。

所以我们需要处理动态地删除/加入一个位置,并维护是否满足所有位置 prei<limi 成立。

设一个计数器 cur 初始为 0。每当有一个 preilimicur 增加 1。则实际上是动态维护 cur,合法等价于 cur=0

离散化 a 后用 set 维护每个数的所有出现位置。就可以动态计算每个位置的 prenxt:因为你注意到删除/加入一个位置只会修改 O(1) 个位置的 prenxt。修改一个位置后重新计算其对 cur 的贡献即可。时间复杂度 O(nlogn)

记录


G. Euclid Guess

考虑欧几里得算法的过程:求两个正整数的 gcd 并使用辗转相除的形式。本题中,有一个初始为空的数组 t,每一次求两个数的 gcd,就把辗转相除过程中的所有非零余数加入 t 中。

现在给你一个长度为 n 的序列 p,你需要构造一个长度不超过 2×104 的数对构成的数列 a,满足:

  • 每个数对的元素都是 [1,m] 之间的正整数

  • 对所有数对的两个数分别求 gcd 后得到的序列 t 可以通过任意排序和 p 完全相同。

无解输出 1n103,1m109

Hint1 当一个数 x 满足 2x+1>m 的时候,这样的数不可能出现在余数序列中。

另一方面,通过一次塞入 (3x,2x),我们可以只塞入 x 这一个数。

换言之,所有小于 13m 的数都没有任何问题,关键是介于三分之一到二分之一的数,这样的数不可能单独被塞入。

Hint2 如果要塞入一个三分之一到二分之一之间的数 x,则其对应的余数序列里,最小的那个数必定是小于三分之一的,且是 x 的约数。

另一方面,单独把这两个数作为一个可能的余数序列,是最优且合法的。

Solution

我第一次独立杀了 2800* 的构造啊,这个题非常值得一做的还是。

第一 2×104 是诈骗,加一个数对肯定至少让 t 的长度增加 1,否则加了没用。所以你的答案长度肯定 n

然后考虑无解。事实上如果想要有一步余数为 a,那么最小的数对是 (2a+1,a+1) 这样第一步余数得到 a。换言之如果 p 中有一个元素 x 使得 2x+1>m 则无解。

换言之,p 中每个元素 <m2

然后考虑对于某些元素 x,你可以直接放一个 (3x,2x) 进去。这样的 xm3。这样这个过程中只会往 t 添加 x 一个数。

所以需要特殊考虑的数 x 都是在区间 (m3,m2) 之间的,称这些数为特殊数。

如果两个数 (a0,a1) 产生的非零余数序列分别为 a2,a3,...,ak1,ak,则 ak 一定整除 a0ak 的任何一个数,因为 ak 就是 (a0,a1)gcd。我们想把特殊数和非特殊数串起来,使得它们构成的非零余数序列可以被某个数对所产生,但这是不好做的。注意到一点事实:两个特殊数不会出现在同一非零余数序列中,否则开始的数对必定有一个数 >m。此外,考虑一个特殊数所在的非零余数序列,序列的最后一个元素必定整除这个特殊数。而我们直接把这两个数作为一个非零余数序列也是合法的。

这样,就转成了一个匹配问题:左部是特殊数,右部是非特殊数。最后的匹配大小应该就是 |L|,否则无解;而 R 中未被匹配到的数 x 都可以通过加入一组 (3x,2x) 的形式进入 t 中,直接网络流即可。

点数是 O(n) 级别的,边数是 O(n2) 级别的,众所周知网络流跑二分图最大匹配复杂度是 O(mn) 所以时间复杂度 O(n2n)。实测最慢点 30ms,直接起飞。

记录


1687

C. Sanae and Giant Robot

给出两个长度为 n 的序列 ai,bi。给出 m 个区间 [li,ri]。然后你可以执行任意次操作:

选择一个区间 [li,ri],满足 j=liriaj=j=lirjbj,然后对每个 j[li,ri],执行 aj=bj

问是否可以将 a 变为 bn,m2×105

Hint1

ci=aibi,然后令 Sici 的前缀和,此时原问题有良好性质。

Solution

送我上 IM 的题。

首先作差,令 ci=aibi。则条件变为 j=liricj=0 此时把 cliri 全部推平成 0,目标是让所有 ci=0

Sc 的前缀和,则条件变为 Sli1=Sr=k,此时把 Sliri 全部推平成 k,目标是让所有 Si=0

到这里我们发现一件事情,就是如果推平的时候 k0,那推了之后是不会更优秀的;如果 k=0,那我们执行一次推平一定是更优秀的。

所以我们可以每次找到一个没有被选中过的区间 [li,ri] 并且满足 Sli1=Sri=0,然后把 Sliri 中的所有非零位置全部推平成 0。考虑到一个区间最多被取出一次,一个位置最多被推平一次,各自可以用 set 去维护。时间复杂度均摊下来 O(nlogn)。(n,m 同阶)。

记录


D. Cute number

g(x)=x2,f(x)=(g(x)+1)2。称一个正整数 x 是好的当且仅当 xg(x)<f(x)x

给出一个长度为 n 的正整数数组 a,求最小的非负整数 k。使得 a1+k,a2+k,...,an+kn 个数字都是好的。

n106,1a1<a2<...<an2×106

Hint1

观察到 k 不会超过 1012 的级别,换言之 g(a1) 不会超过 106 级别。

Hint2

暴力枚举 g(a1) 的最后取值,设 k 是最少的合法增加量使得 g(a1) 是你要枚举的取值,但我们还不能保证其余 n1 个位置都合法,所以还要求出一个最小的增加量 k 使得 g(a1) 不改变的情况下,所有位置都合法。

Hint3

当你确定了 k 以后,设 n 个数里有 cnt 个不同的 g 值,容易证明所有情况的 cnt 之和是 alna 级别的。

所以确定 k 以后,暴力枚举所有不同的 g 值,对于每个 g,做些什么。

Hint4

我们会发现,g 不变的时候,我们只需要调整两个极端的位置,让它们合法即可。

Solution

题目没有说会无解,明示我们 k 存在一个上界:显然最后的 g(a1) 不超过 (an+1)2

a=g(x),那么 a 不超过 an+1。也就是说 a 最后的取值也就是 O(an) 个,这启发我们暴力枚举最后的 a

然后当 g(ai)g(ai+1) 的时候我们称新增了一个段,猜测所有情况的总段数加起来不会太多。因为你 a 特别大的时候,从 a(a+1) 实质上就跨越了 2a+a2 个数,所以肯定最多跨越次数不会超过 ana12a 次,显然小于 ana 次,那么所有 a 的跨越次数加起来就是 O(anlogan) 级别的。

从上面,我们知道了首先可以暴力枚举 a,然后把 a1,a2,...,an 按照 g(ai) 去分组。但是对于每一组,我们还不明确具体做什么。

我们来研究一下条件中的式子。那么有 a2x<(a+1)2,然后 xa2<(a+1)2xxa2+a

下面方便起见更改定义: g(x)=g(x)

不妨设 k 是最小的非负整数使得 g(a1+k)=a。然后此时有些 ai+k 是不会合法的。现在的问题是我们可能还要让 k 加上一个调整量 k 使得所有 ai 满足条件。而这个过程中,如果 ai+k 合法,则 g(ai+k) 应该等于 g(ai+k+k),否则 g(a1+k+k) 一定不是 a 了。而对于不合法的 ai+k,在保证 g(a1+k+k) 不变的情况下,它如果想最后合法,则 g(ai+k+k)=g(ai+k)+1 必须成立。而此时你可以找到这一组内最小的 ai 满足 ai+k 不合法。所以对于每一段你只要找两个位置。而且它们是相邻的,实质上你只需要二分一次。

总复杂度 O(anloganlogn)

记录


1691

E. Number of Groups

给出 n 条线段 [li,ri],每条线段要么是红色,要么是蓝色,记为 ci=0/1

两条线段若异色且有交,则在它们之间连一条无向边。

问最后的连通块个数。n105,1li,ri109

Hint1 扫描线。
Hint2 当把一条线段和若干异色线段合并后,只用保留右端点最大的异色线段。
Solution

考虑离线处理这个问题。离线处理线段/区间的常用套路是扫描线。

离散化 l,r 后从小往大枚举 x,若 x=li 加入线段 i,若 x=ri 则删除线段 i(先处理所有加入,后处理所有删除)。然后加入一条线段时,所有加入过且未被删除的线段就是和它有交的。

显然我们要把线段分成两种颜色存储。每次找异色且与其有交的线段合并即可。但这样不能保证复杂度。特别地,注意到合并过后,异色的集合,只用保留 r 最大的那条线段即可。时间复杂度降为 O(nlogn)

记录

posted on   Cry_For_theMoon  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
 
点击右上角即可分享
微信分享提示