zoukankan      html  css  js  c++  java
  • CodeForces 1311E Construct the Binary Tree

    题意

    给定(n)(d),构造一颗(n)个节点的二叉树(以(1)为根),所有节点到(1)的距离和为(d),不行输出(NO),否则输出(YES)(2)-(n)的父亲编号

    分析

    最大和显然是一条链,如果最大和仍小于(d),则不行,否则先构造出一条链,然后枚举当前的层数,如果当前层数的下一层仍然可以填,则将链的尾端放置在下一层可得到最大的变化,如果这个变化大于所需要的变化,则找到挂置的层数,否则则挂在下一层,若下一层已满,则将所枚举层数下移

    #pragma GCC optimize(3, "Ofast", "inline")
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define ll long long
    #define int ll
    #define ls st<<1
    #define rs st<<1|1
    #define pii pair<int,int>
    #define rep(z, x, y) for(int z=x;z<=y;++z)
    #define com bool operator<(const node &b)
    const int maxn = (ll) 5e3 + 5;
    const int mod = 998244353;
    const int inf = 0x3f3f3f3f;
    int T = 1;
    int pre[maxn];
    set<int> lay[maxn];
    vector<int> son[maxn];
    
    void solve() {
        int n, d;
        cin >> n >> d;
        int now = 0;
        son[1].clear();
        lay[1].clear();
        lay[1].insert(1);
        rep(i, 2, n) {
            pre[i] = i - 1, now += i - 1, lay[i].clear();
            lay[i].insert(i);
            son[i].clear();
            son[i - 1].push_back(i);
        }
        if (now < d) {
            cout << "NO
    ";
            return;
        }
        int nowLay = 1;
        for (int i = n; i >= 1; --i) {
            if (i <= nowLay + 1)
                break;
            int maxx = i - nowLay - 1;
            if (maxx >= now - d) {
                if (lay[i - 1 - (now - d)].empty()) {
                    ++nowLay;
                    ++i;
                    continue;
                }
                int fa = *lay[i - 1 - (now - d)].begin();
                pre[i] = fa;
                now = d;
                break;
            } else {
                now -= maxx;
                int fa = *lay[nowLay].begin();
                son[fa].push_back(i);
                if (son[fa].size() == 2)
                    lay[nowLay].erase(fa);
                son[pre[i]].erase(son[pre[i]].begin());
                pre[i] = fa;
                lay[nowLay + 1].insert(i);
                lay[i].erase(i);
                if (lay[nowLay].empty())
                    ++nowLay;
            }
        }
        if (now != d) {
            cout << "NO
    ";
            return;
        }
        cout << "YES
    ";
        rep(i, 2, n)cout << pre[i] << ' ';
        cout << '
    ';
    }
    
    signed main() {
        start;
        cin >> T;
        while (T--)
            solve();
        return 0;
    }
    
  • 相关阅读:
    ASP.NET学习篇(4)——服务器端的控件【转自www.bitsCN.com】
    sql2005 管道的另一端上无任何进程解决方法
    SQL服务器名称的更改
    如何辨别移动硬盘的好坏
    ADO绑定SQL数据库过程
    SQL变量的使用
    SQL子查询
    什么SQL解发器?
    什么是存储过程呢?
    显式事务和隐式事务之间有什么区别?
  • 原文地址:https://www.cnblogs.com/F-Mu/p/13138164.html
Copyright © 2011-2022 走看看