码迷,mamicode.com
首页 > 其他好文 > 详细

E. Construct the Binary Tree。。。

时间:2020-03-09 10:32:58      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:ram   org   NPU   you   src   length   bug   this   cee   

You are given two integers nn and dd . You need to construct a rooted binary tree consisting of nn vertices with a root at the vertex 11 and the sum of depths of all vertices equals to dd .

A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a vertex vv is the last different from vv vertex on the path from the root to the vertex vv . The depth of the vertex vv is the length of the path from the root to the vertex vv . Children of vertex vv are all vertices for which vv is the parent. The binary tree is such a tree that no vertex has more than 22 children.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1t10001≤t≤1000 ) — the number of test cases.

The only line of each test case contains two integers nn and dd (2n,d50002≤n,d≤5000 ) — the number of vertices in the tree and the required sum of depths of all vertices.

It is guaranteed that the sum of nn and the sum of dd both does not exceed 50005000 (n5000,d5000∑n≤5000,∑d≤5000 ).

Output

For each test case, print the answer.

If it is impossible to construct such a tree, print "NO" (without quotes) in the first line. Otherwise, print "{YES}" in the first line. Then print n1n−1 integers p2,p3,,pnp2,p3,…,pn in the second line, where pipi is the parent of the vertex ii . Note that the sequence of parents you print should describe some binary tree.

Example
Input
Copy
3
5 7
10 19
10 18
Output
Copy
YES
1 2 1 3 
YES
1 2 3 3 9 9 2 1 6 
NO
Note

Pictures corresponding to the first and the second test cases of the example:

技术图片技术图片

 

题解:

Tutorial

1311E - Construct the Binary Tree

This problem has an easy constructive solution. We can find lower and upper bounds on the value of dd for the given nn. If the given dd does not belong to this segment, then the answer is "NO". Otherwise, the answer is "YES" for any dd in this segment.

How to construct it? Let‘s start from the chain. The answer for the chain is the upper bound of dd and it is n(n1)2n(n−1)2. Then let‘s try to decrease the answer by 11 in one move. Let‘s take some leaf vv (the vertex without children) with the smallest depth that is not bad and try to move it up. The definition of badness will be below. To do this, let‘s find such vertex pp that its depth is less than the depth of vv by 22 and it has less than 22 children. If we found such vertex pp then let‘s make vv the child of pp and decrease the answer by one.

If we didn‘t find such vertex pp, I claim that the vertex vv has the minimum possible depth it can have and we should not consider it in the future. Let‘s mark this vertex as bad and continue our algorithm.

If at some moment we cannot find any not bad leaf vv, then the answer is "NO". Otherwise, the answer is "YES".

Time complexity: O(nd)O(nd).

 

Solution

#include <bits/stdc++.h>

using namespace std;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	
	int t;
	cin >> t;
	while (t--) {
		int n, d;
		cin >> n >> d;
		int ld = 0, rd = n * (n - 1) / 2;
		for (int i = 1, cd = 0; i <= n; ++i) {
			if (!(i & (i - 1))) ++cd;
			ld += cd - 1;
		}
		if (!(ld <= d && d <= rd)) {
			cout << "NO" << endl;
			continue;
		}
	
		vector<int> par(n);
		iota(par.begin(), par.end(), -1);
		
		vector<int> cnt(n, 1);
		cnt[n - 1] = 0;
		
		vector<int> bad(n);
		
		vector<int> dep(n);
		iota(dep.begin(), dep.end(), 0);
		
		int cur = n * (n - 1) / 2;
		while (cur > d) {
			int v = -1;
			for (int i = 0; i < n; ++i) {
				if (!bad[i] && cnt[i] == 0 && (v == -1 || dep[v] > dep[i])) {
					v = i;
				}
			}
			assert(v != -1);
			int p = -1;
			for (int i = 0; i < n; ++i) {
				if (cnt[i] < 2 && dep[i] < dep[v] - 1 && (p == -1 || dep[p] < dep[i])) {
					p = i;
				}
			}
			if (p == -1) {
				bad[v] = 1;
				continue;
			}
			assert(dep[v] - dep[p] == 2);
			--cnt[par[v]];
			--dep[v];
			++cnt[p];
			par[v] = p;
			--cur;
		}
	
		cout << "YES" << endl;
		for (int i = 1; i < n; ++i) cout << par[i] + 1 << " ";
		cout << endl;
	}
		
	return 0;
}

//转载于http://codeforces.com/blog/entry/74224

E. Construct the Binary Tree。。。

标签:ram   org   NPU   you   src   length   bug   this   cee   

原文地址:https://www.cnblogs.com/lijiahui-123/p/12447054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!