D. Problem with Random Tests

D. Problem with Random Tests

You are given a string s consisting of n characters. Each character of s is either 0 or 1.

A substring of s is a contiguous subsequence of its characters.

You have to choose two substrings of s (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 s1 be the first substring, s2 be the second chosen substring, and f(si) be the integer such that si is its binary representation (for example, if si is 11010, f(si)=26);
the value is the bitwise OR of f(s1) and f(s2).
Calculate the maximum possible value you can get, and print it in binary representation without leading zeroes.

Input

The first line contains one integer n — the number of characters in s.

The second line contains s itself, consisting of exactly n characters 0 and/or 1.

All non-example tests in this problem are generated randomly: every character of s is chosen independently of other characters; for each character, the probability of it being 1 is exactly 12.

This problem has exactly 40 tests. Tests from 1 to 3 are the examples; tests from 4 to 40 are generated randomly. In tests from 4 to 10, n=5; in tests from 11 to 20, n=1000; in tests from 21 to 40, n=106.

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

 

解题思路

  这题一直看错题,硬是把或看成异或,当时模拟样例的时候还一直出错,还以为是样例给错了,然后拿样例去问同学,结果人家题都没看就问我是不是按位或,当时心态直接炸了。

  首先对于最优解,这两个子串中必然有一个子串是取整个字符串s。这是因为这个是按位或运算,位数越多得到的结果只可能变大而不会减小。考虑此时两个子串中不存在一个子串取整个s,那么我们选择其中一个子串,将其变成字符串s,那么得到的结果不会变得糟糕(因为位数增加)。

  同时也可以发现另外一个子串前缀扩展到s的第一个字符s[1]结果也不会变差。

  那么现在一个子串已经确定了(取整个字符串s),接下来考虑另外一个字符串。

  对于字符串s我们从左往右找到第一个1出现的位置p1,那么s[1p1]内都是都是0,可以发现此时无论另外一个子串怎么取,都不可以将答案的[1,p1]这个区间的任意一个位置置成1,因此答案最大是[p1,n]这个区间内全为1。这时再从p1这个位置开始往右找到第一个0的位置p2,那么s[p1p21]内都是1。很明显我们要在另外一个子串的p2位置取1,才能取到尽可能大的结果,而这个1就要在区间[p1,p21]内取(如果在p2往后取的话,由于位数不足,因此另外一个子串的p2位置必然是0)。那么我们就枚举区间[p1,p21]的每一个1,把这个1放到子串p2这个位置,即这个子串就是s[ii+np2](p1ip21)。前面我们有说这个子串扩展到前缀结果不会变差,可以发现由于此时前缀是 0 0 ... 1 1 1 这个形式,结果也不会比[p1,n]这个区间内全为1的更优,因此在这里是否扩展到前缀对结果没有影响,因此可以不用扩展到前缀。

  然后是时间复杂度的问题,假设第一段连续的1的长度为m,那么时间复杂度就是O(mn),但这题的数据是随机的,01出现的概率均为12,因此如果m要取到20,即第一段有20个连续的1,这个概率大概是106这个量级,即非常的低,因此我们可以认为m是一个比较小的常数,因此时间复杂度可以期望估计为O(n)

  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

posted @   onlyblues  阅读(100)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示