ShanghaiTech新生赛游记

ShanghaiTech “ASFR” Cup 2nd 新生算法马拉松赛游记

比赛题目链接:https://acm.shanghaitech.edu.cn/contest/65293fbd3d772313bb6bdab0/problems

在一些搜索引擎的帮助下拿下11题获得rk7()

题解顺序按照个人过题顺序编写。

A. 命运的齿轮开始转动...

签到人品题,两发过。

B. 逛超市

题目内容有点多,所以一开始想了很多,但解法其实极其简单。
剩下奖品的总数不超过 \(S\) 个,但盲盒中至少剩下了一份奖品。
那么最坏的情况就是奖品只剩下一个,这一个还是价值最小的那个(乐)。

E. 银河系峰会

看到直接间接交流这类的关系,便想到了并查集。
考虑开一个 \(n+m\) 大小的冰茶姬,前 \(n\) 个元素代表 \(n\) 个代表,后 \(m\) 个元素代表 \(m\) 种语言。
如果代表 \(i\) 会语言 \(j\),则将 \(i\) 在的集合与 \(n+j\) 在的集合合并,这样使得能够通过语言直接或间接互通的代表在同一集合下。
最后数一下,除了只有某门语言之外的集合,有几个集合,记为 \(cnt\)。那么将这几个集合合并还需要 \(n-1\) 次。

J. 逛第二次超市

这次是剩下奖品的总数不超过 \(S\) 个,但每种奖项的奖品至少还剩下一份。
所以我们直接先把每个奖品都拿一个填进去,再从小到大往里面填入数,能够使得总期望被拉低即可。
注意总数不要超过 \(S\)

D. 阿斯特莱亚的救赎

做了很久,想了不少做法,但都没有高于 \(O(n^2)\) 的。
所以回过来观察题目性质。
因为我们只考虑部分和是否是 \(n\) 的倍数,不妨将 \({a_i}\) 全部模上 \(n\),将全部运算在模 \(n\) 意义下运算。
考虑对 \({a_i}\) 做前缀和得到 \(s_i\),对 \(s_i\) 分类讨论:
若存在 \(s_i=0\),那么取 \(a_1,a_2\dots a_i\) 即可满足条件。
若不存在 \(s_i=0\),那么\(n\)\(s_i\) 的所有取值可能必然只有 \([1,n-1]\),由鸽巢原理,必然存在 \(s_l=s_r (l<r)\),此时取 \(a_{l+1},a_{l+2}...a_r\) 即可满足条件。
过于精妙了。

F. 树套树套树

这题挺扯的(关于比赛24h后出题人给出使用oeis的提示的这档子事)。
做这题浪费了大概 \(\frac{2}{3}\) 个后半夜。
一开始我通过求差分数组再加回去的方式(因为每次伸展的树枝数更容易求得一点)手玩了 \(20\) 组数据,发现有点像分形,且大概与 \(2^k\) 有关,不过之后就没啥想法了。
然后果断把数列扔到oeis里面,找到python代码翻译成cpp,最后把递归式的前 \(10^6\) 项记忆化一下就A了。
然后开始思考这个式子的组合意义(毕竟想让自己真正意义上A掉),不过只能大概找到规律,没办法完全解释。
(等我看懂了再补)

G. 鼠鼠数数

为了A这个题把早已不会的数位DP重新学了一遍(
这个题属于求第 \(k\) 个满足某种条件的数的类型。
因为要求的数只有两个条件且两个条件都只涉及相邻两位,所以状态与转移的设计为方便。
\(dp_{i,j}\) 为第i位为最高位且为j时,满足题意的数有几个(包含前导0)
那么状态转移方程为:

\[dp_{1,j}=1 \qquad\qquad (0 \leq j \leq 9)\\ dp_{i,j}=\sum_{{\substack{0 \leq k \leq 9\\k \neq j,k+j \neq 9}}} dp_{i-1,j} \qquad (i > 1) \]

然后我们记录一个数组 \(sum_i=sum_{i-1}+\sum_{j=1}^{9} dp_{i,j}\) 表示小于 \(10^i\) 的数中有几个满足题意的数。
最后只要通过扫一遍 \(sum\) 确定第 \(k\) 个数的位数,再逐位计数确定每一位是哪个数。

H. 芙莉莲的迷宫之旅

网格图路径计数问题。
\((x,y)\) 在其他象限情况与第一象限相同,故只讨论第一象限。
\((0,0)\)\((x,y)\)\(R\) 步有解,当且仅当 \(x+y \leq R\)\(2|(R-x-y)\)
之后不难发现,必然有 \(x\) 步向右走,\(y\) 步向上走,剩下 \(R_0=R-x-y\) 步可以分成向上下和向左右的部分。
所以,假设 \(R_0\) 步中向上走 \(i\),则可知总共向上走 \(x+i\) 步,向下走 \(i\) 步,向右走 \(y+\dfrac{R_0}{2}-i\) 步,向左走 \(\dfrac{R_0}{2}-i\) 步,那么通过枚举 \(i\) 可以得到总方案数为:

\[ans=\sum_{i=0}^{\frac{R_0}{2}} \dfrac{R!}{(x+i)!\cdot i!\Big(y+\dfrac{R_0}{2}-i\Big)!\cdot\Big(\dfrac{R_0}{2}-i\Big)!}\\ =\dbinom{R}{\frac{R_0}{2}}\sum_{i=0}^{\frac{R_0}{2}} \dbinom{\frac{R_0}{2}}{i}\dbinom{x+y+\frac{R_0}{2}}{x+i}\\ =\dbinom{R}{\frac{R_0}{2}}\sum_{i=0}^{\frac{R_0}{2}} \dbinom{\frac{R_0}{2}}{\frac{R_0}{2}-i}\dbinom{R-\frac{R_0}{2}}{x+i} \]

这样可以得到60分做法。
然后运用公式:

\[\sum_{i=0}^{k} \dbinom{n}{i}\dbinom{m}{k-i} = \dbinom{n+m}{k} \]

(组合意义:要从 \(m+n\) 个元素中取 \(k\) 个,可将所有元素分成 \(m\) 个与 \(n\) 个两组,分类考虑从两组中分别取几个。)
化简得到:

\[ans=\dbinom{R}{\frac{R_0}{2}}\dbinom{R}{x+\frac{R_0}{2}} \]

L. 钝角

做这题浪费了大概 \(\frac{1}{2}\) 个后半夜,边做边复习仅有的寄算几何知识(
对于30分做法,枚举每个点的组合,判断求和即可,复杂度为 \(O(n^3)\),考虑优化。
因为以上暴力做法是扫过每一个点的最优策略,要想更优,则在确定一条边以后,必然有一些点是不需要重复再扫一遍的。
根据向量叉乘的分配率,我们发现在某一条边确定后,可以把一些与这条边夹角为钝角的边以向量加法的形式加起来再做叉乘求答案,所以我们考虑极角排序+双指针。
对于每一个点 \(I\),以此为原点,记录其他点的极角与对应的向量,再做一遍极角排序,并按照极角序复制一遍序列,方便后续操作。
因为要将某一个向量与所有能对答案产生贡献的向量之和做叉乘得到该向量对总答案的贡献,不重不漏,所以我们要规定向量夹角以顺时针为正,只统计往顺时针方向转的钝角,并扩展到任意角,即复制出的后半段极角都要加上 \(2\pi\)
于是我们顺时针枚举除 \(I\) 点之外的每一个点 \(J\),将与这个点对应的向量所成夹角在 \((\frac{\pi}{2},\pi)\) 范围的向量在极角序上的区间 \([l,r]\),以及其向量和记录下来。则边 \(IJ\) 对答案的贡献就是向量 \(\overrightarrow{IJ}\) 与记录的总合的叉乘。然后往顺时针转到下一个点,将通过叉乘将夹角小于 \(\pi\) 的点计入,通过点乘将夹角小于 \(\frac{\pi}{2}\) 的点去除。最后算出全部答案。
一开始写了很久,只有80分,然后对拍,拍 n=20 的情况拍不出。然后拍 n=100 的,拍了1000组左右才拍出来,然后又花很长时间写输出中间变量的语句,最后一查发现generator没判断每个点互不相同。于是修改了之后边对拍边写别的题,才找数据。
最后发现是在有多个点共线的时候,因为计入条件写了叉乘值 \(\geq 0\) 导致共线的点被重复统计。最后改成叉乘值 \(> 0\) 或者角度相同就过了。
写完后再一次体会到什么叫如释重负(乐)。

C. 挑战量子密码学

回过头来看这个神级诈骗题。
显然,平常的做法只能够拿到20分,毕竟这题 \(N<2^{640}\) 的数据范围就连 \(O(n^{\frac{1}{4}})\) 的 Pollard-Rho 算法也得叹一口气。所以这题显然没有什么正经的做法。
那么如何入手,这个sb一开始并不知道,只能望着 \(a\oplus x\oplus x=a\) 的提示发呆。
然后这个sb在看live等转场的时候,重新检查了数据输入格式,恍然大悟。

Pre-Coinred 2023/10/15 19:56:48
woc我tm就是个sb
Pre-Coinred 2023/10/15 19:56:53
谢谢谢谢
Pre-Coinred 2023/10/15 19:56:56
Orz

由于Python的字符串有 s=input().split()k=len(s) 之类的操作,所以我们可以在操作具体数据之前便能够得知所有 \(k_i\) 的值。于是根据异或的自反性,通过 \(k_i \oplus k'_i\) 便可以得到 \(M_{i-1}\)。然后我们就能够得知除了 \(M_n\) 之外的所有 \(M\)

因为当 \(i=n\),最多有 \(10\) 个密钥,每个密钥的大小都不超过 \(13\),所以用最基本的办法处理即可。
而对于 \(i\not=n\),稍加处理便可以知道 \(p_1+p_2\)\(p_1\times p_2\),韦达定理解方程即可。
逆天。

I. 芙莉莲的第二次迷宫之旅

与H题类似的,假设 \(R_0\) 步中向上走 \(i\),则可知总共向上走 \(x+i\) 步,向下走 \(i\) 步,向右走 \(y+\dfrac{R_0}{2}-i\) 步,向左走 \(\dfrac{R_0}{2}-i\) 步,那么通过枚举 \(i\) 可以算出总方案数。
现在考虑在该情况下的方案数。
因为格点全部都在第一象限中,所以我们在任何时候向上走的步数不能小于向下的,向右的不能小于向左的。于是我们不难想到Catalan数的其中一个组合意义。
类似于Catalan数,我们要求由 \(n\)\(+1\)\(m\)\(-1\) 组成的 \(n+m\) 个数 \(a_1,a_2, \cdots ,a_{n+m}~(n>m)\),其部分和满足 \(a_1+a_2+ \cdots +a_k \geq 0~(k=1,2,3, \cdots ,n+m)\),有多少个满足条件的数列?
答案应当为:

\[f(n,m)=\dbinom{n+m}{m}-\dbinom{n+m}{m-1} \]

证明如下:

正难则反,考虑不合法序列的数量。
对于一个不合法的序列,必然存在一个最小的 \(2p+1\),使得 \(a_1+a_2+ \cdots +a_{2p+1}\) 恰好为 \(-1\),此时该段中有 \(p\)\(+1\)\(p+1\)\(-1\)。然后将这一段所有数取相反数便可以得到一个唯一的 \(n+1\)\(+1\)\(m-1\)\(-1\) 的序列。
同样的,对于一个 \(n+1\)\(+1\)\(m-1\)\(-1\) 的序列,也必然存在一个最小的 \(2p+1\),使得 \(a_1+a_2+ \cdots +a_{2p+1}\) 恰好为 \(1\),此时该段中有 \(p+1\)\(+1\)\(p\)\(-1\)。然后将这一段所有数取相反数便可以得到一个唯一的由 \(n\)\(+1\)\(m\)\(-1\) 组成的不合法的序列。
所以这样的两个数列构成双射。
所以不合法序列的数量就是由 \(n+1\)\(+1\)\(m-1\)\(-1\) 组成的序列的数量,即 \(\dbinom{n+m}{m-1}\)
因为由 \(n\)\(+1\)\(m\)\(-1\) 组成的序列的数量为 \(\dbinom{n+m}{m}\)
所以合法序列的数量就是 \(\dbinom{n+m}{m}-\dbinom{n+m}{m-1}\)

求出这个后,便可得出总得答案数为:

\[ans=\sum_{i=0}^{\frac{R_0}{2}} f(x+i,i) f\Big(y+\dfrac{R_0}{2}-i,\dfrac{R_0}{2}-i\Big)\\ =\sum_{i=0}^{\frac{R_0}{2}} \Bigg[\dbinom{x+2i}{i}-\dbinom{x+2i}{i-1}\Bigg]\Bigg[\dbinom{y+R_0-2i}{\frac{R_0}{2}-i}-\dbinom{y+R_0-2i}{\frac{R_0}{2}-i-1}\Bigg] \]

(听说还可以进一步优化(?))

K. 听说我们缺字符串题

M. 造CPU

没做,摆了,以后再说

posted @ 2023-10-21 16:11  Coinred  阅读(88)  评论(0编辑  收藏  举报