2023 年上海市大学生程序设计竞赛 - 七月赛 题解

上海科技大学程序设计竞赛社团 edited 1 年,8 月前

狗吃骨头

an 表示还有 n 只狗准备去吃骨头时骨头的数量 am 就是我们要求的答案。
由题意可以得到递推关系
(ai1)m1m=ai1

(1 代表吃一根,m1m 代表吃一份),利用待定系数法,转换为指数数列

an+m1=mm1(an1+m1)

bn=an+m1,即 bn=mm1bn1,立即有

bn=(mm1)n1b1

由于要满足吃骨头的规律,an 必须满足 m|(an1),并且an,bn必须是整数。

m>2 时,由于 m(m1) (i.e. mm1 互质),因此为了保证b1bm 是整数,必须有 b1=K(m1)m1 其中 K 是正整数。

此外,因为最后一条狗也要能够按照规律吃骨头,因此 m|(a11),代入a1=b1m+1

m|(K(m1)m1m)

仍然由于m(m1),由 Bezout 定理,m|gcd(K(m1)m1,m),因此最小的 K=m。故 b1=m(m1)m1,bm=(mm1)m1b1=mm

代入式子,am=bmm+1=mmm+1。当m=2时,递推式由于不成立,这是因为 a2=3 会导致第二只狗没有足够的骨头吃,上述推导没有考虑”剩下的骨头非负”这一要求。

因此答案为

{mmm+1m>27m=2

注意边界情况啊,少年

音乐之城

先考虑 t=0 的情况,此时最长的 combo 数量是 bi=ai%x 的最常连续相同子段。

s 表示启动时间,不妨假设 s<0,那么一个音符能够被击打到,当且仅当 y.|y|tai+ysmodx。那么通过枚举 y 就能计算出 smodx 的值,那么便求得了一个音符对应的能够被击打的 s 的集合,设为 Ii。由于|Ii|64,那么可以用状态压缩至一个 64 位数,记为E[i]

那么一段音符 l,l+1,,r 能够被击打到,当且仅当 IlIl+1Ir,这即当且仅当 E[i]E[i+1]E[r]0 ( 表示二进制与)。因此可以通过预处理出 E 数组,并使用 st表维护区间 (二进制与) 。枚举一个 l,那么就能够通过二分查找最远的 r,使得 E[l]E[l+1]E[r]0,那么 [l,r] 就是一段 combo 区间。总复杂度 O(nlogn+nx64)

地球签证

很明显 ii2 构成一颗二叉树关系。 设 dp[i,a,b,0/1]表示考虑标号为 i 的子树,其中有 a 个被分为”男性”,b个被分为”女性”,且当前点被分为男性/女性,的最大多样性值。枚举 i 的性别,然后枚举 i 的两个儿子的性别,就能够得到转移方程。

然而 a+b=size[i]size 表示子树大小。因此只需要记录一个维度即可。设 dp[i,a,0/1] 表示考虑标号为 i 的子树,其中有 a 个被分为”男性”,且当前点被分为男性/女性,的最大多样性值。那么转移方程为,同样枚举 i 的性别,然后枚举 i 的两个儿子的性别,就能够得到转移方程。树上背包复杂度 O(n2)

回文文回

那么用类似于 manacher 的算法处理回文串,得到的 manacher 中的辅助数组 p[i], 可以用这个计算所有可能的本质不同的回文子串,使用字符串哈希,将所有本质不同的子串的哈希值放入一个unordered_set(哈希) 中。考虑如何处理询问,使用根号分治:

询问的时候枚举短串,然后把答案记忆化到 std::unordered_map 里,就能AC。这不是数据水,而是复杂度正确

(使用回文自动机可以避开字符串哈希,复杂度同样为O(NN))

PS: 为了卡掉复杂度不对的做法,造数据时想办法卡满了分块的复杂度,导致一些大常数程序无法通过

研究方向

结论:一个研究方向 (i,j,k) 可行,当且仅当 gcd(j,k)|i

先假设我们只能进行一次操作(定义一次操作为若干次 improve 后再 reduce),那么 i 能化为 j 当且仅当下列方程有解:

j=i+ykx(x>0y0x,yN)

xjyk=i(x>0y0x,yN)

由 Bezout 定理,这个方程如果要有解,必要条件是满足 gcd(j,k)|i。假设一组特解为 x0jy0k=i。由通解公式得 x=x0+kt,y=y0+jt 。 令 t 足够大即得两个正整数解。因此,如果只能进行一次操作(ie. 若干次 improve 再 reduce 一次),(i,j,k) 可行当且仅当 gcd(j,k)|i

综上我们证明了,如果只能进行一次操作,那么 (i,j,k) 可行当且仅当 gcd(j,k)|i。利用数学归纳法容易证明,如果可以进行 K.K>1 次操作,那么 (i,j,k) 可行仍然当且仅当 gcd(j,k)|i

因此

W=i=1nj=1nk=1n[gcd(j,k)|i]=i=1nj=1nk=1nd=1n[gcd(j,k)=d][d|i]=i=1nd=1n[d|i]j=1nk=1n[gcd(j,k)=d]=i=1nd=1n[d|i]j=1nk=1n[d|j][d|k][gcd(jd,kd)=1]=i=1nd=1n[d|i]j=1ndk=1nd[gcd(j,k)=1]=i=1nd=1n[d|i](1+2j=1ndϕ(j))=d=1ni=1n[d|i](1+2j=1ndϕ(j))=d=1nnd(1+2j=1ndϕ(j))

利用数论分块快速求上述式子,利用杜教筛等算法可以在 O(n23) 的时间内计算一次 i=1mϕ(i) 的前缀和;然而在本题中,所有需要用到的 ϕ 的前缀和都在第一次杜教筛算法(ie. 计算 i=1Nϕ(i) , cf. oi-wiki )中计算过了,因此只需要一遍杜教筛,用map把计算过的值进行记忆化,避免重复计算。总复杂度 O(n23)

比赛情况

本次比赛中出现了比较多的小问题,比如输入格式上下文不符、空格换行不分、题目描述不清、测试数据有误等等。这些问题都是由于我们的疏忽导致的,在这里向大家真诚道歉。希望大家在本题解下方点赞支持一下

尽管我们在赛时采取了迅速有效的办法进行补救(以上问题均在 120 秒内得到妥善解决),但是对比赛的影响还是不可避免的。希望能够得到大家的谅解。尤其是对于较早遇到问题的同学,比如在”问答”中指出题目问题的同学等,请您联系我们,我们会尽可能以纪念品来向您表达歉意和感谢。

后记

感谢大家参加2023 年上海市大学生程序设计竞赛 - 七月赛,希望大家能够在比赛中有所收获。如果有任何疑问,欢迎在讨论区指正。如果你的做法更厉害或者有其他想吐槽或者讨论的,欢迎在此处评论区,或者ShanghaiTech-ACM OJ指出。

鸣谢:上海交通大学俞勇老师、华东师范大学肖春芸老师、华东师范大学汪鼎尊同学、上海科技大学科道书院汤飞龙老师、信息学院屠可伟、杨思蓓、闻天明老师的大力协助。没有你们本场场比赛难以顺利进行。此外,感谢上海科技大学黄磊、曹宇涵同学,清华大学彭思进、高子翼同学,北京师范大学香港浸会大学联合国际学院李欣泽同学和北京理工大学周行健同学对于本套试题的贡献。此致,

敬礼!祝各位选手前程似锦!


上海科技大学程序设计竞赛社团

地址:上海市浦东新区华夏中路393号上海科技大学信息学院 1B-205 室

邮箱: acm@shanghaitech.edu.cn

网址: acm.shanghaitech.edu.cn

Comments