#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000009;
LL w[N];
int k, v, u;
bool dfs( int x, int height, int value ){
//if( value == 9 && height == k ) cout << "here: " << x << endl;
if( height == k ){
if( !w[x] && x % 2 == 0 ){
w[x] = value;
return true;
}
else if( !w[x] && x % 2 == 1 && value >= w[x - 1] ){
w[x] = value;
return true;
}
return false;
}
if( w[x] <= value && dfs( x * 2, height + 1, value ) ){
if( w[x] < value ) w[x] = value;
return true;
}
if( w[x] <= value && dfs( x * 2 + 1, height + 1, value ) ){
if( w[x] < value ) w[x] = value;
return true;
}
return false;
}
int main(){
cin >> k;
for( int i = 1; i <= k; i ++ ){
int l = (1 << (k-i)), r = l * 2;
for( int j = l; j < r; j ++ ){
cin >> v;
//cout << v << " ";
if( !dfs( j, k - i, v ) ){
cout << "No Solution";
return 0;
}
}
//cout << endl;
}
cin >> u;
if( !dfs( 1, 0, u ) ){
cout << "No Solution";
return 0;
}
int l = ( 1 << k );
for( int i = l; i < l * 2; i ++ ){
cout << w[i];
if( i < l * 2 - 1 ) cout << ' ';
}
cout << endl;
return 0;
}
模拟一下样例可以看出,比赛的过程是一个满二叉树;
对于满二叉树,咱们可以用一个数组来表示。
表示方法跟y总的算法基础课,堆那一节的二叉树表示方法一致
咱们的答案就位于$2^k$-$2^{k+1}$的下标范围内。
然后,咱们可以从第一轮比赛开始放(把能力值放到答案区间内)
放的时候遵循一下规则
1.要是左右儿子都空,就先放到左儿子
2.要是左儿子非空,并且右儿子为空,就比较一下
(1)要是当前要放的值value$>=$左儿子,就放到右儿子,返回$true$
(2)要是小于,就返回$false$
3.对于不是位于$2^k$-$2^{k+1}$的下标范围内空位,我们要存一下该子数的最大值。