zoukankan      html  css  js  c++  java
  • [CF] CF1311E Construct the Binary Tree

    Description

    (Link)

    Solution

    注意到深度和最小的情况就是完全二叉树,最大的就是链。那么我们先构造出一棵完全二叉树,再一步步调整节点变成链。

    不妨令最初的链为(1,2,4,...,2^k)。设当前考虑到了点(i),链底为(now),目前深度和距离(d)还差(r)

    考虑到把(i)挂到(now)下面,深度增加了(cnt=dep[now]+1-dep[i])。所以,如果(cnt<r),就可以把(i)直接挂过来,(r-=cnt)

    否则,说明如果挂过来,深度和会大于(d)。所以,我们要使(cnt)变小。

    (i)不方便动,从而我们改变(now)即可。在(cnt==r)之前,不断使(now=fa[now]),从而(cnt--)

    最后依次输出即可。(数据太弱了,可以做到(sum{n}leq{10^7})的)

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int t, n, d, fa[5005], dep[5005];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    int main()
    {
    	t = read();
    	while (t -- )
    	{
    		n = read(), d = read();
    		int sum = 0;
    		dep[1] = 0;
    		for (int i = 2; i <= n; i ++ )
    		{
    			fa[i] = i >> 1;
    			dep[i] = dep[fa[i]] + 1;
    			sum += dep[i];
    		}
    		if (sum > d)
    		{
    			puts("NO");
    			continue;;
    		}
    		if (sum == d)
    		{
    			puts("YES");
    			for (int i = 2; i <= n; i ++ )
    				printf("%d ", fa[i]);
    			puts("");
    			continue;
    		}
    		int r = d - sum, now = (int)(pow(2, (int)log2(n))), fl = 0;
    		for (int i = n; i >= 1; i -- )
    		{
    			if ((i & (i - 1)) == 0) continue;
    			int cnt = dep[now] + 1 - dep[i];
    			if (cnt < r)
    			{
    				fa[i] = now, now = i;
    				r -= cnt, dep[i] = dep[fa[i]] + 1;
    			}
    			else
    			{
    				while (r < cnt) {now = fa[now], cnt -- ;}
    				fl = 1; fa[i] = now; break;
    			}
    		}
    		if (!fl)
    		{
    			puts("NO");
    			continue;
    		}
    		puts("YES");
    		for (int i = 2; i <= n; i ++ )
    			printf("%d ", fa[i]);
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    TCHAR字符串查找&反向查找字符串
    如何判断一个文本文件的编码
    用NETSH WINSOCK RESET命令修复网络
    #define和typedef在windows上的应用
    Visual Studio Code (vscode)编译C++
    win32 Message(MSG)消息处理
    HBRUSH to RGB value
    InvalidateRect和UpdateWindow
    Informatic ETL开发步骤
    【非官方方式】获取Disconf动态更新的配置文件的值
  • 原文地址:https://www.cnblogs.com/andysj/p/14482820.html
Copyright © 2011-2022 走看看