zoukankan      html  css  js  c++  java
  • codeforce 1311E. Construct the Binary Tree (构造,就是个模拟)

    ACM思维题训练集合
    You are given two integers n and d. You need to construct a rooted binary tree consisting of n vertices with a root at the vertex 1 and the sum of depths of all vertices equals to d.

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

    You have to answer t independent test cases.

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

    The only line of each test case contains two integers n and d (2≤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 n and the sum of d both does not exceed 5000 (∑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 n−1 integers p2,p3,…,pn in the second line, where pi is the parent of the vertex i. Note that the sequence of parents you print should describe some binary tree.

    Example
    inputCopy
    3
    5 7
    10 19
    10 18
    outputCopy
    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:

    在这里插入图片描述
    丫的,改了一天。
    如果b在构造的树的深度最大(左偏或右偏树)和最小(满二叉树)之内就能构成,然后从左偏树开始不断的将低端的点向上移动,知道达到要求。

    #include <bits/stdc++.h>
    using namespace std;
    int f[210];
    inline void solve()
    {
        memset(f, 0, sizeof(f));
        int n, d, maxd = 0;
        scanf("%d %d", &n, &d);
        --n;
        if (d > n * (n + 1) / 2)
        {
            printf("NO
    ");
            return;
        } //1
        for (int i = 1;; ++i)
        {
            maxd = i;
            if (n > (1 << i))
            {
                d -= i * (1 << i);
                f[i] = 1 << i;
                n -= 1 << i;
            }
            else
            {
                d -= i * n;
                f[i] = n;
                n -= n;
                break;
            }
        }
        if (d < 0)
        {
            printf("NO
    ");
            return;
        }
        while (1)
        {
            if (d == 0)
                break;
            int p;
            for (p = maxd; p >= 1; --p)
                if (f[p] > 1)
                    break;
            --d;
            --f[p];
            ++f[p + 1];
            if (p + 1 > maxd)
                maxd = p + 1;
        }
        printf("YES
    ");
        int p = 1, np = 1, cnt;
        for (int i = 1; i <= maxd; ++i)
        {
            int t = p;
            cnt = 0;
            for (int j = 1; j <= f[i]; ++j)
            {
                ++p;
                ++cnt;
                if (cnt >= 3)
                {
                    ++np;
                    cnt = 1;
                } 
                printf("%d ", np);
            }
            np = t + 1;
        }
        printf("
    ");
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int i = 1; i <= t; ++i)
            solve();
        return 0;
    }
    
    
  • 相关阅读:
    winserver-性能监视器计数器介绍
    winserver-性能监视器
    winserver-凭据管理(credential manager)
    The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "server_name" was unable to begin a distributed transaction.
    pandas-排序
    SQL SERVER-跟踪标记
    WinSCP
    SSL证书
    Powershell-修改文件夹权限
    fiddler 插件开发
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798410.html
Copyright © 2011-2022 走看看