edu 137 D & 杭电春季赛8 1005(数据随机生成)
edu137D
简洁题意:给定一个01串,选定其中的任意两个非空子串,使得它们最低位对齐后的或运算结果最大。
有两个需要注意到的性质:
- 选取的两个子串一定都是这两个串的前缀。若某个子串选取的不是前缀,则总是可以加上它的未选取的前缀部分,而结果一定不会更劣。
- 选取的某个前缀一定是整个字符串本身。若不是,则这两个子串一定均存在未选的至少后1位。在这两个子串的后面均加上这一位也一定不会使结果更劣。
因此可以确定:这两个子串中,其中一个是整个字符串本身,另一个是这个字符串的某一个前缀。暴力枚举所有结果仍然会是 \(O(n^{2})\) 的复杂度。考虑数据生成随机带来的优化复杂度:
注意到,这个字符串中 \(0\) 第一次出现的位置一定不会很靠后(例如连续 \(20\) 个 \(1\),概率为 \(\frac{1}{2^{20}}\),几乎不可能)。可以发现这个或运算相当于将这个字符串的某个前缀与整个字符串的后缀相或。而想让最终或运算的答案最大,则一定要将这个最高位0变为1。那么这个前缀向右移动的距离一定不会很多(最多为前缀1的长度次),否则不能让这个最高位0变为1,不是最优解。则暴力枚举前缀向右移动的距离即可。
1005
考虑在 \(T\) 中所有长度为 \(N\) 的连续段,需注意到一个性质:与 \(A\) 异或后结果最大的连续段,满足异或后的结果中 连续 \(1\) 的前缀长度最长(证明略)。
而由于数据生成随机,因此显然这个最长长度不会很长(例如连续 \(20\) 个 \(1\),概率为 \(\frac{1}{2^{20}}\),几乎不可能)。因此对于 \(T\) 中每个长度为 \(N\) 的连续段,暴力查找最长的前缀 \(1\) 即可。一旦中断就退出。
由于可能有 多个相同的 包含最长前缀长度 的连续段,因此需要将这些连续段的开头位置都存下来,取它们的最大值。具体细节见代码。