这套做的比较顺。
题也很好。
T1
一个简单的贪心。
我们二分能够无伤通过的蛤个数。
check就用之前用烂了的队列来check。
然后我们知道无伤通过最多一定对应这所有的石头被踩完,因为这样可以让每只蛤单次跳跃距离的最大值尽量的小。
这也就是说两种最优操作是合在一起的,有点像\(CSP-2019 D2T2\)。
那么,二分出来剩下的就是必然要跳出大于\(D\)的了,我们取最小的几只,让他们一步从\(1\)跳过去。
另外一种情况是没有蛤可以无伤过。
这时候就让最便宜的那只去踩地雷,踩过所有的石头,然后剩下的直接跳过去就可以了。
T2
简单的推式。
我们要求的是:
\[\sum\limits_{i=0}^{n}\sum\limits_{j=1}^{a+id}\sum\limits_{l=1}^{j}l^k\]
\(k\in[0,3000],n,a,d\in[0,123456789]\)。
这样只能够把复杂度转成\(O(K^2)\)的。
稍微推一下,设\(B_i\)为伯努利数第\(i\)项。
那么:
\[\sum\limits_{i=0}^{n}\binom{n+1}{i}B_i^{-}=0\]
求出\(B^{-}\)后求\(B^{+}\)
\[B_i^{+}=(-1)^iB_i^{-}\]
一下令\(B_i=B_i^{+}\)
关于自然数幂和的式子是:
\[\sum\limits_{i=1}^{n}i^k=\frac{1}{k+1}\sum\limits_{i=0}^{k}\binom{k+1}{i}B_in^{k+1-i}\]
然后就可以直接拆式子了。
\[\begin{aligned}
ans&=\sum\limits_{i=0}^{n}\sum\limits_{j=1}^{a+id}\sum\limits_{l=1}^{j}l^k\&=\sum\limits_{i=0}^{n}\sum\limits_{j=1}^{a+id}\frac{1}{k+1}\sum\limits_{l=0}^{k}\binom{k+1}{l}B_lj^{k+1-l}\&=\frac{1}{k+1}\sum\limits_{l=0}^{k}\binom{k+1}{l}B_l\sum\limits_{i=0}^{n}\sum\limits_{j=1}^{a+id}j^{k+1-l}\&=\frac{1}{k+1}\sum\limits_{l=0}^{k}\binom{k+1}{l}B_lg(k+1-l)\g(l)&=\sum\limits_{i=0}^{n}\sum\limits_{j=1}^{a+id}j^l\&=\sum\limits_{i=0}^{n}\frac{1}{l+1}\sum\limits_{k=0}^{l}\binom{l+1}{k}B_k(a+id)^{l+1-k}\&=\frac{1}{l+1}\sum\limits_{k=0}^{l}\binom{l+1}{k}B_k\sum\limits_{i=0}^{n}(a+id)^{l+1-k}\&=\frac{1}{l+1}\sum\limits_{k=0}^{l}\binom{l+1}{k}B_kf(l-k+1)\f(r)&=\sum\limits_{i=0}^{n}(a+id)^{r}\&=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{r}\binom{r}{j}a^j(id)^{r-j}\&=\sum\limits_{j=0}^{r}\binom{r}{j}a^jd^{r-j}\sum\limits_{i=0}^{n}i^{r-j}\&=\sum\limits_{j=0}^{r}\binom{r}{j}a^jd^{r-j}h(r-j)\h(p)&=\sum\limits_{i=0}^{n}i^{p}\&=[p=0]+\sum\limits_{i=1}^{n}i^{p}\&=[p=0]+\frac{1}{p+1}\sum\limits_{k=0}^{p}\binom{p+1}{i}B_in^{p-i+1}\\end{aligned}\]
\(O(n^2)\)求出\(h,f,g\)然后分别回代即可。
注意特判掉\(p=0\)的情况。
模数加一次就爆int??
T3
\(SAM+LCT\)
好题。
我们用\(LCT\)维护\(lastpos\)。
然后写一个可持久化线段树来维护答案。
对于每条实链来说,他们的\(lastpos\)都是相等的,我们用他们中\(len\)最大的来更新答案数组。
因为在\(access\)的时候这一条链上的点都是这个位置的字符串的重复出现。
我们在加入一个新节点的时候,在\(access\)的过程中,首先把每条实链中的所有的部分的\(len\)的最大值加入到这条实链的\(lastpos\)上就可以了。
然后由于要保证每条实链的\(lastpos\)时刻相等。
我们发现在\(link\)的时候会进行 \(lastpos\)赋值操作,而\(cut\)则不会。
所以我们的\(cut\)不能调用\(access\)函数,防止将不同\(lastpos\)的实链串联起来。
这样的话维护\(SAM\)的\(parent\)树该怎么做呢?
我们不\(cut\),而是直接把\(nq\)怼进树里。
具体来说。
我们找到\(q\)所在\(splay\)的前驱,然后把其前驱的右儿子变成\(nq\)即可,多打几个特判就行了。
然后查询的时候二分答案。
只需要判断第\(r\)棵可持久化线段树中的\([l+mid-1,r]\)区间中的最大值是否是比\(mid\)要大就行了。
时间复杂度的话,由于\(access\)的均摊复杂度是\(O(nlogn)\)的,而可持久化线段树的修改是\(logn\)的。
那么时空都是:\(O(nlog^2n)\)
原文地址:https://www.cnblogs.com/Lrefrain/p/12182321.html