「JOI 2018 Final」毒蛇越狱
「JOI 2018 Final」毒蛇越狱
Algorithm 1: 暴力计算
对于所有$0,1,?$组成的$3^n$种串处理出答案
具体的,对于当前串包含的最后一个$?$位置,枚举它变成0/1的答案,按照一定的顺序累和即可
(代码可以在Algo2里面看到)
Algorithm 2 : Meet in the Middle
$3^{20}$太大,优化上面的暴力,容易想到把复杂度从预处理分一部分给查询
取出$n$中前$k$个位置,这些位置不处理$3^k$,而是让每个询问暴力地去枚举这些位置上的$?$变成$0/1$
显然每个询问有最多$2^k$次枚举,即复杂度为$O(Q\cdot 2^k)$
对于剩下的$n-k$个位置,采取上面的暴力方法预处理,三进制枚举,预处理复杂度为$O(2^k3^{n-k})$
因此复杂度为$O(Q\cdot 2^k +2^k3^{n-k})$,计算在$k=6,7$时复杂度约为$3.5\cdot 10^8$
(这是一个非常稳的复杂度)
1 |
|
Algorithm 3 : 高位前缀和+容斥
起始学过高位前缀和/FMT的看到这个题第一反应可能都是这个。。
-> 对于$?$的位置,直接赋值成1,然后对于这个数从高位前缀和里查询
然后你发现不知道怎么对于1的把0的去掉
显然这个可以通过一个暴力的容斥来完成,枚举一些1的位置变成0,然后就是容斥的奇数减偶数加
复杂度为$O(Q\cdot 2^{1的个数}\ \ \ \ \ )$
同理,处理高位后缀和,复杂度为$\begin{aligned}O(Q\cdot 2^{0的个数}\ \ \ \ )\end{aligned}$
而直接暴力枚举$?$变成0/1,复杂度为$\begin{aligned}O(Q\cdot 2^{?的个数}\ \ \ \ \ )\end{aligned}$
综合这三种算法,选一个更优的做,就得到一个复杂度为
$\begin{aligned}O(Q \ \cdot 2^{ \begin{aligned}\ \ \ \ \ \ \ \ \ \ \min\lbrace 1的个数,0的个数,?的个数\rbrace\end{aligned} })\ \ \ \ \ \ \end{aligned}$显然查询复杂度就是$O(Q\cdot 2^{\lfloor \frac{n} {3}\rfloor }=Q\cdot 2^6)$
算上预处理,复杂度为$O(2^nn+Q\cdot 2^6)$
1 |
|