2023.02.13 模拟赛小结

更好的阅读体验戳此进入

赛时思路

T1

CF840C On the Bench

给定序列,求序列有多少个排列满足任意相邻两数之积非完全平方数。

赛时最终想到的是质因数分解后,两数合成之后若所有质因数幂次均为偶数则为完全平方数,依此可以 O(n2log2a) 处理每个数可以(或不可以)和哪些数相邻,这样的话如果求的不是排列而是任意序列那就是一个非常朴素的 DP 了,不过排列就完全没有想到什么复杂度正确的好做法,唯一想到了一个 O(n5) 的不知道正确性的区间 DP 做法,即考虑 dp(l,r,x,y) 表示 [l,r] 生成的左端点为 x 右端点为 y 的排列,然后枚举分割点转移,当然这个东西既不知道正确性又没有部分分,所以直接考虑 next_permutation()。期望 10pts

Code

T2

CF819D Mister B and Astronomers

存在一个星星每 T 秒闪烁一次,存在 n 个科学家围成一圈循环观测星星,第一个在 0 秒观测,第二个在 a2 秒观测,第三个在 a2+a3 秒观测, 第一个科学家在 a1+a2+a3++an 观测,。对于 t[0,T),若星星第一次闪烁在 t 秒,那么第一次观测到这个星星的科学家将会获得 1 的贡献,求每个科学家的贡献。

一道十分高妙的 exgcd 题,赛时大概是发现了会根据同余成环,环数是 gcd(a,T),这样的话部分分就是暴力枚举每个 t 然后一直枚举是否出现与对应科学家同余并计算贡献即可,不难想到若两者互质那么一定有解,而在暴力分中两者不互质的部分可能存在不再同一环内导致无解,这里一个简单的办法就是均分时间然后卡时即可,期望得分 20pts

Code

T3

没找到原题。

CF793F Julia the snail

大概就是存在一个一维空间,最小位置在 1,最大位置为 n,你可以随时减少位置,但只能使用 m 个单向传送门从 liriq 次询问给定限定 [xi,yi] 表示你初始在 xi,并位置最小不能小于 xi,最大不能大于 yi,求最大能到达哪个位置。

部分分给的还行,前 20pts 白送的,后面两个部分分是传送门无重叠和询问无重叠,怎么说呢,想到的几个思路最后都被我卡掉了,理论上满的时候都是 m2 的,不过数据比较弱又多过了 20pts

Code

正解

T1

首先有一个更高妙的转换,可以认为 50% 的部分分是一个提示,即所有数都是质数的时候问题转化为不能有相同的数相邻,而正解可以先考虑将每个数的平方质因子全部去除,这样问题即可转化为要求相邻两数不同,考虑如何处理。

存在朴素 DP,考虑按序添加数(这个东西怎么处理赛时属实是想了好久假了好久),不难发现添加 ai+1[1,i] 的排列时,有四种情况,即两侧均为 ai+1,一侧为 ai+1,两侧相同且均不为 ai+1,两侧不同且均不为 ai+1

显然处理排列时原序列不同顺序本质相同,于是考虑将原序列排序,依次处理 si 表示前 i 个数里有多少个 ai+1

同时令 dp(i,j,k) 表示考虑前 i 个数,有 j 个两侧数相同且不为 ai+1,有 k 个两侧数均为 ai+1,显然对于前两种情况,考虑应有 2×si 个位置,每存在一个相邻两侧均为 ai+1 的就会减少 1,即转移为:

dp(i,j,k)×(2×sik)dp(i+1,j,k+1)

对于第三种情况,同理:

dp(i,j,k)×jdp(i+1,j1,k)

对于第四种情况,同理:

dp(i,j,k)×(i+1(2×sik)j)dp(i+1,j,k)

同时这里我们注意一个问题,当 aiai+1 时,我们原来记录的 k 的意义会改变,换句话说原来的 k 会在新的这一次变为 j,于是此时将所有 dp(i,j,k) 的贡献转移到 dp(i,j+k,0) 即可。

最终答案显然为 dp(n,0,0),复杂度 O(n3)

双倍经验 LG-P4448 [AHOI2018初中组]球球的排列

Code

T2

首先不难想到,令 S=ai,第 i 个科学家观测时间为 j=2iaj+kS,kN,令 ti=j=2iaj,同时对于 T,假设本次初始时间为 ξ,那么可以认为需要找到第一个满足 ti+kSξ(modT)

对于后者式子不难发现其为经典的群论套路,即我们发现对于某个科学家的初始点 ti,可以认为每次模意义下步进 S,此时会构成 gcd(S,T) 个环,环长均为 Tgcd(S,T),或者说每连续 gcd(S,T) 个数均属于不同的环。关于这个性质似乎特别显然,不过这里我们也简单证明一下:

显然我们要证明的即为如下式子:

i[0,T),ii+gcd(S,T)(modgcd(S,T))
i[0,T),t(0,gcd(S,T)),i+ti(modgcd(S,T))

证明均显然。

此时我们考虑,对于一个环内的所有科学家,ξ 为环上某一点的贡献,我们要找到的就是第一个,或者说其减少最少个 S 遇到的 ti,这个东西不难想到,对于两个同环科学家 ti,tj,且 tjti 之后,两者之间模意义下距离了多少个 S 就代表 i 的答案由多少。而对于不同环中显然互相无交无关联。

所以我们可以考虑对于一个环内的所有科学家 t1,t2,,我们如果能够按照其在环内的遍历顺序排序,或者说满足 ti 之后的 tj 一定是 ti 经过最小次模意义下加 S 的操作得到的(这里如何做我们后文再叙),然后遍历一遍,此时对于相邻的 ti<tj(注意此时的 < 意义是我们重载过的小于号,且两者相邻或 i 为末尾 j 为初始)存在:

ti+xStj(modT)

转化后得到:

Sx+Ty=tjti

并且显然满足 gcd(S,T)tjti,满足 exgcd 的限制,注意此时 y 是任意的,所以仅需求出 x 的最小非负整数解,其即代表了 ti 对应科学家的总贡献,也就是答案。同时注意若环内仅有一个科学家则其贡献直接为 Tgcd(S,T)

现在我们在将目光移回上文所述的排序过程,考虑发现该限制对应到上述方程的意义就是 x 最小的解,如果满足 ST 那么我们是可以通过乘逆元转换为 ti×S1modT 的偏序关系,但本题显然不满足,于是不难想到若其初始时位置为 pi=timodgcd(S,T),那么一定存在 pi+kSti(modT),发现此方程亦为 exgcd 形式,转换为 Sx+Ty=tipi,求出 x 的最小非负整数解即可得到其在环中对应的位置,以其为关键字进行排序则一定满足我们上述的偏序关系。而解相同的,即同环模意义下同位置的,不难想到我们优先保留 ti 较小的即可,较后的一定为 0

最终复杂度卡在排序和两次 exgcd 上,为 O(nlogn)

Tips:还有些小细节,观察所有式子发现,对于所有 Sti 都可以并需要进行 SSmodT,titimodT,这是对答案无影响的。对于在 set 中排除同环模意义下同位置的,可以考虑利用 C++ 特性,重载小于号,使得只保留相同第一关键字中最先加入的,可以证明最先加入的一定最小。

附:好久没写 exgcd 了,简单重推一下吧:

要求 ax+by=gcd(a,b)

显然存在 bx+(amodb)y=gcd(b,amodb)

gcd(a,b)=gcd(b,amodb)

整理并展开 amodb 得到 ax+by=bx+(aab×b)y

则显然有 x=y,y=xab×y

问题规模缩减,不断递归,直到最终 gcd=0 则回溯 x=1,y=0 即可。

此时得到任意解,令 d=tjtigcd(S,T),显然整除,则 xx×d,yy×d 即可,同时注意我们想要求得 x 得最小非负解,发现方程通解为 x+kTgcd(S,T),ykSgcd(S,T),以 Tgcd(S,T) 为模数对 x 取模转正后求出对应的 y 即可找到 x 的最小非负解。

Code

T3

首先记录一下 @sssmzy 的部分分做法:

对于传送门无重叠,加个倍增即可保证复杂度。

对于询问无重叠,考虑暴力建图即可均摊正确复杂度。

正解分块或吉司机线段树。

 

//TODO (先去学吉司机线段树了。。

UPD

update-2023_02_13 初稿