• CF1311E Construct the Binary Tree


    膜这场比赛的 (rk1)
    (color{black}Acolor{red}{lex\_Wei})

    这题应该是这场比赛最难的题了

    容易发现,二叉树的下一层不会超过这一层的 (2) 倍,所以我们先构造出来一颗尽量满的二叉树,然后慢慢向下调整,调整的方法是从最上面一个一个弄下来。

    然后你慢慢调整的复杂度最多是 (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 << '
    ' ;
    	}	
    	return 0 ;
    }
    
  • 相关阅读:
    1026. 程序运行时间(15)
    C语言字符串/数组去重
    1025. 反转链表 (25)
    1024. 科学计数法 (20)
    1023. 组个最小数 (20)
    1022. D进制的A+B (20)
    1021. 个位数统计 (15)
    1020. 月饼 (25)
    前端001/正则表达式
    SSM001/构建maven多模块项目
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12374601.html
Copyright © 2020-2023  润新知