省选模拟5 题解

A. 青蛙

因为每个青蛙都可以一步跳到终点。

所以二分几个青蛙可以无消耗跳到终点,只要让最贵的几个青蛙跳过去。

之后特判一下一个青蛙都跳不过去的情况就好了。

 

B. 一起自习的日子

伯努利数练习题。

不断的把自然数幂和用伯努利数展开,顺便二项式展开一下就好了。

另外分析可知原式可以化为一个多项式的形式,所以通过插值也可以求出。

 

C. 字符串

考虑维护SAM中每个点的$last$,表示这个点endpos集合的最后一个元素。

维护数组$Ans[r,l]$表示题意中要求的答案,首先将$Ans[r,l]$直接继承$Ans[r-1,l]$

对于$np$节点,会导致祖先链上每个点的endpos集合新添元素$n$,也就是修改$last$。

只需要考虑$n$与最后一次出现的$last$两个点所形成的字符串。

对于$np$祖先链上的点$p$,分两种情况更新$Ans[r,l]$:

对于$last-l+1>=len_p$,直接对$len_p$取$max$。

对于$last-l+1<len_p$,对$last-l+1$取$max$。

容易发现这个东西是分别对等差数列和定值取$max$。

因为数据很水,用可持久化线段树优化一下这个东西,通过从大神$G$_$keng$那里学来的卡内存技巧(避免在同一个根重复新建节点)就可以AC了。

正解要优化暴力跳祖先的过程。

发现$np$的更新祖先链上所有点的$last$为$n$的操作与LCT中access的操作是一致的,似乎都对应着推平的性质。

所以不妨维护这个性质,使一条实链的$last$为一致的。

可以发现对于一条实链上$last$相同的所有$p$,只要维护最大的$len_p$。

在access的同时通过每条实链的最优的$len_p$更新答案就好了。

需要注意的一点是,在access的过程中,更新答案前,需要先截断不想要的深度部分,避免不想要的$len_p$上传到当前节点。

一个更简单的做法是只插入单点,在查询时套个二分答案,顺便维护区间最值就好了。

posted @ 2020-01-12 12:17  skyh  阅读(208)  评论(0编辑  收藏  举报