6.16赛后总结

6.16模拟赛赛后总结

赛时历程

​ 上午七点十分拿到题面然后进行通读,略微思考了一下T1和T2的暴力,到T3时就读不懂题了,尝试多读一会儿理解一下,七点半了,打算直接开始暴力。

​ 先敲T1的最基础的 \(n^2\)\(a_i\le30\) 的分数,枚举区间然后对区间和lowbit一次判断即可,这个分数少的可怜,然后用\(set\)模拟一下大数进位,这个有\(n^2logn\) 可过且\(a_i\le10^9\)的部分分,这个还调了一会儿,两个部分总共有30分。大约八点十分,开始写T2的暴力,这个暴力就简单明了许多,\(n^2\)的模拟非常朴素,然后看这个分数的划分,纯 \(n^2\) 可以稳定拿到的分数是30分,加了剪枝运气好能够过\(30000\)的,总共有40分,对着暴力卡常,造数据,大概就九点半了。

​ 上一个厕所,回来思考T3的暴力,发现阶乘枚举排列再找最大完美匹配是一个复杂度很高的算法,偏偏这道题的时间限制是1s。

​ 终于是没有打T3的任何算法,怎么写都不能让我在1e8的時間内通过。T1和T2想再优化也感觉难,并不知道怎么优化。

​ 到了比赛结束。

赛后发现

1 得分30+40. 仍然有一道题是0分。

2 今天好好的按顺序来做事情,不过思路跟不上,搞完暴力之后只能陷入思考的漩涡,需要多思考提升思维。

技术总结

T1 是笛卡尔树+hash,首先是一个结论:若\(2^x=\sum\limits_{i=l}^{r}a_i\),那么\(x\le max\{a_l,a_{l+1},...,a_r\}+log_2len\) ,这个很容易证明,假设每个点都相等,那么最后的和是\(2^a*len\),不会超过\(2^{a+len}\).但这个东西似乎不容易想到,也不知道是什么样的经验让人往\(x\)的取值范围上去想,想到这个之后,我们发现对于一个区间我们经过\(log\)个枚举就可以判断出是否存在一个\(x\)能够满足区间的和为一个整次幂,具体来说,如果固定一个点为最大值,枚举\(2^x\),然后让这个左端点的前缀和加上\(2^x\)能够找到一个位置p使得前缀和\(s[p]=s[l]+2^x\),那么这个区间就是满足要求的,为了快速找到这个位置,考虑用hash将前缀和映射到它的位置上,每次枚举答案的时候,在表中查找\(s[l]+2^x\)出现的位置,这个位置的前缀和的hash值如果和当前的\(s[l]+2^x\)的hash值相等,那么就代表\(l\)到这个位置的区间和是\(2^x\),累计一个\(ans\)。暴力的枚举依然有\(n^2\)的复杂度,所以考虑分治,我们每次确定的答案是基于一个区间里的最大值来"抬升"枚举的,所以说考虑跨过一个最大值的区间对答案的贡献,考虑建出笛卡尔树,搞一个大根堆样子的,从顶开始往下走就保证每次的根的值是最大的,然后考虑一个“启发式”的枚举,左右子树哪个小枚举哪个,假设左子树小,那么枚举左端点,然后枚举答案,hash查找位置在右子树的hash值,如果能够找到,ans++,这样做的复杂度就是\(O(nlog_2^2n)\)的。实现上就是建造笛卡尔树和hash的问题了。

T2 是一个分块多项式,暂且只会\(n^2\)暴力。

T3 是一个结论性的“暴力”。如果知道结论,可以很快的算出每个位置的贡献,场上可以尝试打表,虽然规律挺难发现的(况且我也没打表这个心思)。结论是,第\(i\)小的数被计算了$ (\dfrac{n}{2}!)^2\dbinom{i-1}{\frac{n}{2}-1}$次。证明比较难。

posted @ 2021-06-16 22:17  explorerxx  阅读(37)  评论(0编辑  收藏  举报