Educational Codeforces Round 140——D. Playoff

338 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

Educational Codeforces Round 140——D. Playoff

Problem - D - Codeforces

2n2n teams participate in a playoff tournament. The tournament consists of 2n−12n−1 games. They are held as follows: in the first phase of the tournament, the teams are split into pairs: team 11 plays against team 22, team 33 plays against team 44, and so on (so, 2n−12n−1 games are played in that phase). When a team loses a game, it is eliminated, and each game results in elimination of one team (there are no ties). After that, only 2n−12n−1 teams remain. If only one team remains, it is declared the champion; otherwise, the second phase begins, where 2n−22n−2 games are played: in the first one of them, the winner of the game "11 vs 22" plays against the winner of the game "33 vs 44", then the winner of the game "55 vs 66" plays against the winner of the game "77 vs 88", and so on. This process repeats until only one team remains.

The skill level of the ii-th team is pipi, where pp is a permutation of integers 11, 22, ..., 2n2n (a permutation is an array where each element from 11 to 2n2n occurs exactly once).

You are given a string ss which consists of nn characters. These characters denote the results of games in each phase of the tournament as follows:

  • if sisi is equal to 0, then during the ii-th phase (the phase with 2n−i2n−i games), in each match, the team with the lower skill level wins;
  • if sisi is equal to 1, then during the ii-th phase (the phase with 2n−i2n−i games), in each match, the team with the higher skill level wins.

Let's say that an integer xx is winning if it is possible to find a permutation pp such that the team with skill xx wins the tournament. Find all winning integers.

Input

The first line contains one integer nn (1≤n≤181≤n≤18).

The second line contains the string ss of length nn consisting of the characters 0 and/or 1.

Output

Print all the winning integers xx in ascending order.

Examples

input

3
101

output

4 5 6 7 

input

1
1

output

2 

input

2
01

output

2 3 

问题解析

题目是说现在一共有2^n个选手(编号1、2、……、2^n)打n场比赛,两两对决只能胜出一个,给一个长度为n的字符串,如果i是1说明第i场比赛是数字大的人赢,是0说明是数字小的人赢。比赛的选手顺序你来定,问你最后获胜的人可能有哪些。

我们先不管总人数多少,我们想一下,如果前两场比赛都是1,那第二场结束之后,活下来的最小的数可能是谁:

  1. 对于第一场,我们想要谁活下来,只需要给他安排一个数字比它小的队手就行。那么2到2^n的选手都有可能活,除了1,因为1不可能赢。
  2. 对于第二场也是同理,但这次活下来的不是3到2^n。我们可以想一下,对于第一场,如果2活下来了,那么必定是1和2打,那么就没有比三小的了,第一场比赛中,3就肯定会被淘汰。那么此时除了2外最小的就是4了,第二场我们只要安排2和4打,4就能活下来。

也就是说,第二场后活下来的人可能是4到2^n。

我们可以以此类推,第三场活下来的可能是8到2^n,第四场是16到2^n……

而且也不用考虑中间有没有0的情况,就算有0,也是小的能活下来,对我们的结果没有影响。

同理,可以转换一下场次是0的情况。

我们可以得到结论,如果有x场1的比赛,那么能活下来的最小数是2^x;如果有y场0的比赛,那么能活下来的最大数是2^n - 2^y。

我们只要记录出现的1和0的次数,然后从最小数输出到最大数就行。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>//#pragma GCC optimize(2)
//#pragma GCC optimize(3)#define endl '\n'
//#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 998244353;
​
void solve()
{
    int n, cnt = 0;
    string s;
    cin >> n >> s;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == '0')cnt++;
    }
    int res = pow(2, n);
    int r = res-pow(2, cnt) + 1, l = pow(2, n - cnt);
    for (int i = l; i <= r; i++)cout << i << " ";
}
​
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
    //cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}