バイナリツリーを構築CF1311E

フィルムゲーム\(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 ;
}

おすすめ

転載: www.cnblogs.com/Isaunoya/p/12374601.html