D. Problem with Random Tests
D. Problem with Random Tests
You are given a string consisting of characters. Each character of is either or .
A substring of is a contiguous subsequence of its characters.
You have to choose two substrings of (possibly intersecting, possibly the same, possibly non-intersecting — just any two substrings). After choosing them, you calculate the value of the chosen pair of substrings as follows:
let be the first substring, be the second chosen substring, and be the integer such that is its binary representation (for example, if is , );
the value is the bitwise OR of and .
Calculate the maximum possible value you can get, and print it in binary representation without leading zeroes.
Input
The first line contains one integer — the number of characters in .
The second line contains itself, consisting of exactly characters and/or .
All non-example tests in this problem are generated randomly: every character of is chosen independently of other characters; for each character, the probability of it being is exactly .
This problem has exactly tests. Tests from to are the examples; tests from to are generated randomly. In tests from to , ; in tests from to , ; in tests from to , .
Hacks are forbidden in this problem.
Output
Print the maximum possible value you can get in binary representation without leading zeroes.
Examples
input
5 11010
output
11111
input
7 1110010
output
1111110
input
4 0000
output
0
解题思路
这题一直看错题,硬是把或看成异或,当时模拟样例的时候还一直出错,还以为是样例给错了,然后拿样例去问同学,结果人家题都没看就问我是不是按位或,当时心态直接炸了。
首先对于最优解,这两个子串中必然有一个子串是取整个字符串。这是因为这个是按位或运算,位数越多得到的结果只可能变大而不会减小。考虑此时两个子串中不存在一个子串取整个,那么我们选择其中一个子串,将其变成字符串,那么得到的结果不会变得糟糕(因为位数增加)。
同时也可以发现另外一个子串前缀扩展到的第一个字符结果也不会变差。
那么现在一个子串已经确定了(取整个字符串),接下来考虑另外一个字符串。
对于字符串我们从左往右找到第一个出现的位置,那么内都是都是,可以发现此时无论另外一个子串怎么取,都不可以将答案的这个区间的任意一个位置置成,因此答案最大是这个区间内全为。这时再从这个位置开始往右找到第一个的位置,那么内都是。很明显我们要在另外一个子串的位置取,才能取到尽可能大的结果,而这个就要在区间内取(如果在往后取的话,由于位数不足,因此另外一个子串的位置必然是)。那么我们就枚举区间的每一个,把这个放到子串这个位置,即这个子串就是。前面我们有说这个子串扩展到前缀结果不会变差,可以发现由于此时前缀是 0 0 ... 1 1 1 这个形式,结果也不会比这个区间内全为的更优,因此在这里是否扩展到前缀对结果没有影响,因此可以不用扩展到前缀。
然后是时间复杂度的问题,假设第一段连续的的长度为,那么时间复杂度就是,但这题的数据是随机的,和出现的概率均为,因此如果要取到,即第一段有个连续的,这个概率大概是这个量级,即非常的低,因此我们可以认为是一个比较小的常数,因此时间复杂度可以期望估计为。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() { 5 int n; 6 string s; 7 cin >> n >> s; 8 9 int p1 = s.find('1'); 10 if (p1 == -1) { 11 cout << '0'; 12 return 0; 13 } 14 15 int p2 = s.find('0', p1); 16 string ret = s; 17 for (int i = p1; i < p2; i++) { 18 string t = s; 19 for (int j = i + n - 1 - p2, k = n - 1; j >= i; j--, k--) { 20 t[k] |= s[j]; 21 } 22 ret = max(ret, t); 23 } 24 cout << ret.substr(ret.find('1')); 25 26 return 0; 27 }
参考资料
Educational Codeforces Round 137 Editorial:https://codeforces.com/blog/entry/108153
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16815463.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效