设蚂蚁
[PA 2019] Desant
让求取到最小值的方案数,看上去就不太可做。再结合数据范围,考虑 exp 做法。
一个暴力是:按值域从小往大填数,一个数的贡献就是它在填进序列时在它后面已经填好的数。
状压每个位置有没有填数可以得到简单的 \(O(2^n\text{poly}(n))\) 的做法。
考虑能不能合并一些对逆序对的贡献本质相同的状态。
经过观察可以发现,假设现在考虑完了前 \(t\) 大的数,那么相邻两个 \(\leq t\) 的数只选第一个和只选第二个是没有区别的。
扩展一下就是:对于一个极长的只包含 \(\leq t\) 的数的区间,我们只关心这个区间内选了多少个数。
来估算一下状态量:
先假设能给这个 \(t\) 个数任意分段,根据经典结论,每段长最好为 2,也就是状态的数量级是 \(O(3^{\frac{t}{2}})\),而这要求 \(t<\dfrac{2n}{3}\)。
如果 \(t\ge \dfrac{2n}{3}\),那么尽可能均分状态量是最大的,数量级是 \((\dfrac{t}{n-t+1}+1)^{n-t+1}\),这大概是 \(\sum\limits_{1\leq x\leq \frac{n}{3}} (\dfrac{n}{x})^x\),也就是 \(\sum\limits_{3\leq x\leq n} x^{\frac{n}{x}}\),在 \(3\) 处取到最值,后面指数级减小。
所以我们说明了状态量是 \(O(3^{\frac{n}{3}}n)\) 的。
最后 dp 的复杂度是 \(O(3^{\frac{n}{3}}n^2)\),手写哈希表可以通过。
[PA 2021] Desant 2
由于 \(k\) 是常数,以 \(k\) 为块长对序列分块,建立一个 \(k\times \lceil\dfrac{n}{k}\rceil\) 的网格图,图上 \((i,j)\) 格子代表序列中 \((i-1)\times k+j\) 位置的士兵。
那么 dp 的过程相当于:网格图上每个格子 \((i,j)\) 能花费 0 的代价向右走(每一行最右边的格子走到下一行开头),或者花费 \(s_{(i+1,j-1)}-s_{(i,j-1)}\) 的代价向下走一格(\(s_{(i,j)}\) 表示格子 \((i,j)\) 在序列中的前缀和),要求从一个点 dp 到另一个点的最大代价。
网格图上路径统计问题容易想到分治,每次从横竖两个方向较大的一维选出一条中线,然后枚举中线上的每个点,求它到两侧每个点的最大代价,然后对于一组询问,统计在这个点的贡献。需要注意,这个点应在询问两点在序列中位置的中间。
手玩一下可以发现,递归处理一个子矩形时,要把起点终点都被这个子矩形包含的询问都处理。
还有一种 case ,画竖线分治时可能在线异侧的一组询问最长路不经过这条线上的点,但它一定会经过当前子矩形最右边一列,所以再对这一列统计一遍答案。但这种 case 只需要在第一次划竖线时考虑,所以不会显著增加常数。
分治的复杂度是 \(f(n)=O(n\sqrt{n})+2f(n/2)=O(n\sqrt{n})\) 的。
[PA 2024] Desant 3
似乎一眼很难想到有什么 poly 或者比较快的 exp 做法。
这个对 2 取模非常神秘,考虑找双射把一些 case 抵消掉。
考虑第一个操作,如果这两个位置的值是 10,那么经过这次操作,这两个位置的值和 01 是没有区别的。所以如果第一个操作的两个位置的值不相等,它们对答案的贡献是 0。
由此可以想到依次考虑每个操作,维护每个位置的状态,分别是“不确定(x)”、“0”、“1”。
如果考虑到的操作的两个位置都不确定,那么要求这两个位置数值相等,枚举是什么,状态会产生两个。
如果考虑到的操作的两个位置都确定,直接模拟 swap,状态量不变。
现在要考虑只有一个位置确定该怎么办:经过观察可以发现,如果形如 “x0”,那么可以变成 “0x”;如果形如 “1x”,可以变成 “x1”。以此类推,状态量不变。
最后对所有最终状态统计答案即可。
可以发现,只有两个位置都不确定的时候才会状态量翻倍,这件事最多发生 \(\lfloor\dfrac{n}{2}\rfloor\) 次,所以每一轮状态量最多是 \(O(2^{\frac{n}{2}})\) 的。
最后复杂度就是 \(O(2^{\frac{n}{2}}(m+n^3))\),(\(n^3\) 是统计答案,当然这部分也可以做到更低)。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号