フィルムゲーム\(RK1 \)
\(\カラーブラック{A} \カラーレッド{} {レックス\ _Wei} \)
この問題は、ゲームの中で最も困難な問題であるべき
簡単にはバイナリ層の下に、このレベルを超えることはありません、見つけるために、(\ 2)\それでは、完全なバイナリツリー、ゆっくりと下方修正、一つ上位の1から調整方法を構築してみましょう、回降ります。
そして、あなたはゆっくりと、ほとんどの複雑さを調整\(D \) 、の複雑\(O(D)\)
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 5e3 + 5;
int n , d , p[maxn] , fa[maxn] ;
vector < int > dep[maxn] ;
signed main() {
int t;
cin >> t ;
while(t --) {
memset(p , 0 , sizeof(p)) , memset(fa , 0 , sizeof(fa)) ;
cin >> n >> d ;
int sum = 0 , bs = 0 ;
for(int i = 1 ; i <= n ;) {
int rem = min(n - i + 1 , 1 << bs) ;
p[bs] = rem , sum += rem * bs;
i += rem , bs ++ ;
}
if(sum > d) {
puts("no") ;
continue ;
}
int pos = bs;
while(sum < d) {
int k = 0 ;
for(int i = 1 ; i <= n ; i ++)
if((p[i] - 1) * 2 >= p[i + 1] + 1) {
k = i ;
break ;
}
if(! k)
break ;
sum ++ , p[k] -- , p[k + 1] ++ ;
}
if(sum < d) {
puts("no") ;
continue ;
}
puts("yes") ;
int cnt = 1 ;
for(int i = 0 ; i <= n ; i ++)
dep[i].clear() ;
dep[0].push_back(1);
dep[0].push_back(1);
for(int i = 1 ; i <= n ; i ++) {
while(p[i] --) {
fa[++ cnt] = dep[i - 1].back() ;
dep[i].push_back(cnt) ;
dep[i].push_back(cnt) ;
dep[i - 1].pop_back() ;
}
}
for(int i = 2 ; i <= n ; i ++)
cout << fa[i] << ' ' ;
cout << '\n' ;
}
return 0 ;
}