PKUSC2018题解

PKUSC2018题解

真实排名

分别考虑第\(i\)个人翻倍和不翻倍的情况,组合数算一下即可,务必注意实现细节。

代码

最大前缀和

\(sum_s\)表示集合\(\sum_{i\in s} a_i\)\(f_s\)表示最大前缀和等于\(sum_s\)的方案数,\(g_s\)表示选出集合\(s\)排成的最大前缀和均不大于\(0\)的方案数。
因为最终的答案肯定是最大前缀和所在的位置\(pos\)后面一定不存在有一段前缀和大于\(0\),否则向后更新还可以更优。
令全集为\(U\)那么

\[Ans=\sum_{S\subseteq U} sum_S\times f_S\times g_{\complement_U S} \]

现在主要是考虑如何求\(f,g\)

考虑主动转移,由后往前插入数字\(i\),那么\(f_S\rightarrow f_{S\cup \{i\}},sum_S>0\),因为这样的话从i向后选一定会更优;\(g\)的转移比较简单,就是\(g_S\rightarrow g_{S\cup \{i\}},sum_{S\cup\{i\}}\leq 0\)

代码

主斗地

待填

星际穿越

\(L(i)=\min_{j=i}^nl_j\),首先你从一个点\(i\)起跳你的往左的可达区间为\([l_i,i)\),然后第二步跳就可以跳到\([L(l_i),l_i)\),然后一直跳就是这么个情况:\([L(L(...L(l_i))),上一次落脚点)\)

直接预处理一个跳到另外一个是\(O(n^2)\)的有\(70pts\),考虑怎么优化。

令倍增数组\(f_{i,j}\)表示从\(j\)左跳\(2^i\)下跳到哪,\(g_{i,j}\)表示\([f_{i,j},j]\)中所需贡献是多少。

那么你每次倍增求出\(x\rightarrow l\)的代价然后减去\(x\rightarrow r+1\)的代价即可,倍增的具体过程见代码。

代码

神仙的游戏

考虑长度为\(len\)\(border\)的性质,就是说对于长度为\(n\)的字符串\(s\)\(s[1...len]=s[n-len+1,n]\)(这不是定义吗)
也就是说位置\(i\equiv j\;(\bmod\;n-len)\)的话,\(i,j\)的数字相等。

那么对于一个不同的\(0,1\)假设他们的位置之差为\(x\),假设不成立,则有\(x \equiv 0\;(\bmod\;n-len\)),即对于\(y|x\),长度\(n-y\)\(border\)不满足条件。

然后\(O(n^2)\)地做这个东西是\(67pts\),想办法优化。

构造多项式

\[A(x)=\sum_{i=0}^{n-1}[s_i=0]x^i\\ B(x)=\sum_{i=0}^{n-1}[s_i=1]x^i \]

因为我们要求确定差值,而多项式乘法能做的事是求出确定和,我们可以将\(A,B\)任意一个多项式\(reverse\)就可以做到了,最后枚举长度\(len\)的倍数,如果\(C=A\times B\)没有地方的\(C[n-1-k\cdot len]\geq 1\)以及\([n-1+k\cdot len]\geq 1\),那么长度\(len\)就满足条件,这一部分复杂度是调和级数的。

总复杂度\(O(n\log n+n\ln n)\)

代码

PKUSC

待填

posted @ 2019-12-04 22:25  heyujun  阅读(212)  评论(1编辑  收藏  举报