首页 > 其他分享 >CF1917F Construct Tree

CF1917F Construct Tree

时间:2024-01-26 10:33:59浏览次数:28  
标签:le frac int Tree Construct 构造 端点 直径 CF1917F

Link:http://codeforces.com/problemset/problem/1917/F

知识点:背包,构造

简述

\(T\) 组数据,每组数据给定参数 \(d\) 与一长度为 \(n\) 的数列 \(l\),仅需判断是否可以构造出一棵树,满足:

  • 树的所有边长与数列元素一一对应。
  • 树的直径为 \(d\)。

\(1\le T\le 250\),\(2\le n\le 2000\),\(1\le l_i\le d\le 2000\),\(\sum n\le 2000\)。
2S,256MB。

分析

先和 dztle 讨论出一堆结论:

首先若存在 \(l_{i} + l_{j}>d\) 显然无解。

否则若仅存在唯一的 \(l_i>\frac{d}{2}\),则这条边一定在直径上,则此时最可行的构造是用其他边构造出一条长为 \(d-l_i\) 的链与 \(l_i\) 相连构成直径,然后将其他边直接接到 \(l_i\) 靠近直径中点的端点。直接背包判断即可。

否则考虑先构造出长为 \(d\) 的直径,考虑其他边应该接到哪里:

  • 发现所有边直接连到距离直径的中点最近的点 \(m\)上是最可行的。
  • 若 \(m\) 与较近的直径端点距离为 \(d'\)(显然有 \(d'\le \frac{d}{2}\))。则若所有边的长度不大于 \(d'\) 说明构造合法。
  • 为什么合法?考虑一条边 \(l_i(l_i\le d')\) 位于该构造中的什么位置:
    • 边在 \(m\) 与较近的直径端点的链上,则显然有 \(l_i\le d'\le \frac{d}{2}\)。
    • 边在 \(m\) 与较远的直径端点的链上,则有 \(l_i<d'<\frac{d}{2}, d'+l_i\le d\),则直径合法。
    • 边不在直径上且与 \(m\) 相连,则有 \(d'+l_i\le d, d - d' + l_i\le d - d' + d' = d\),则直径合法。
  • 由上述讨论可知当 \(\forall 1\le i\le n, l_i\le d'\) 时在这棵树上所有边都有自己要做的事,所以构造合法。否则必然出现与直径为 \(d\) 冲突的情况。

于是同样考虑背包,首先想到设 \(f_i\) 表示构造出长度为 \(i\) 的链时,最靠近 \(\frac{d}{2}\) 的位置与较近的端点的距离。初始化 \(f_0=0, \forall 1\le i\le d, f_i = -\infin\),转移时枚举当前要加入的边 \(l_i\),再枚举加入边后的链长 \(j\),则有转移:

\[\begin{cases} f_j\leftarrow f_{j-l_i} + l_i &(f_{j - l_i} + l_i\le \frac{d}{2})\\ f_j\leftarrow f_{j - l_i} &\text{otherwise} \end{cases}\]

然后发现这个状态有点问题,有可能长度为 \(l-a_i\) 的链存在多种构造使得最靠近 \(\frac{d}{2}\) 的位置与较近的端点的距离不同,为了考虑周全应当把这些情况都记录下来。于是考虑修改状态将 \(f\) 设为 bitset,表示构造出长度为 \(i\) 的链时,最靠近 \(\frac{d}{2}\) 的位置与较近的端点的距离为某个值是否可行。初始化 \(f_{0, 0} = \text{true}\) 同样修改上述两种转移的形式:

  • \(f_j\leftarrow f_{j-l_i} + l_i\),等价于 \(f_j\) 按位或上 \(f_{j-l_i}\) 左移 \(l_i\) 位的前 \(\frac{d}{2}\) 位。
  • \(f_j\leftarrow f_{j - l_i}\),等价于 \(f_j\) 直接或上 \(f_{j-l_i}\)。

最后检查 \(f_d\) 最右侧的 1 的位置是否大于最长的边即可。

总时间复杂度大概是 \(O\left( \frac{n^2d}{w} \right)\),\(w = 64\),反正能过吸吸

代码

//知识点:背包
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2010;
//=============================================================
int n, d, ans, a[kN];
bool g[kN];
std::bitset <kN> f[kN], h;
//=============================================================
bool DP1() {
  g[0] = 1;
  for (int i = 1; i <= d; ++ i) g[i] = 0;
  for (int i = 1; i < n; ++ i) {
    for (int j = d - a[n]; j >= a[i]; -- j) {
      g[j] |= g[j - a[i]];
    }
  }
  return g[d - a[n]];
}
bool DP2() {
  h.reset();
  for (int i = 0; i <= d / 2; ++ i) h.set(i);
  for (int i = 0; i <= d; ++ i) f[i].reset();
  f[0].set(0);
  
  for (int i = 1; i <= n; ++ i) {
    for (int j = d; j >= a[i]; -- j) {
      f[j] |= f[j - a[i]] | ((f[j - a[i]] << a[i]) & h);
    }
  }
  return f[d]._Find_next(a[n] - 1) != f[d].size();
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(false);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n >> d;
    for (int i = 1; i <= n; ++ i) std::cin >> a[i];
    std::sort(a + 1, a + n + 1);
    if (a[n] + a[n - 1] > d) {
      ans = 0;
    } else if (a[n] > d / 2) {
      ans = DP1();
    } else {
      ans = DP2();
    }
    std::cout << (ans ? "Yes\n" : "No\n");
  }
  return 0;
}

标签:le,frac,int,Tree,Construct,构造,端点,直径,CF1917F
From: https://www.cnblogs.com/luckyblock/p/17988785

相关文章

  • Link-cut Tree
    这可能是我第一次学数据结构如此绝望链剖分重链剖分使用静态数据结构维护实链剖分(LCT)使用splay维护对每个节点,选择一个儿子作为实边,其他为虚边实链用splay维护虚边认父不认子,连接两个splay长链剖分查询修改链上信息随意换根动态维护连通性LCT核心操作access(x)从指......
  • C# AVEVA MARINE DRAWING TREE VIEW 快速读取方法,速度真的很快
    一般来讲我们使用MARAPI里面的ElementChildFirstGet和ElementSiblingNextGet函数去遍历而获得图元'''<summary>'''获取当前视图的全部的子视图的句柄'''</summary>'''<paramname="draftApp">M......
  • ABC337G Tree Inversion
    思路对于每个\(1\lei\len\)的\(i\)都要求答案,那我们考虑dp,去思考如何转移\(f_i\)。先不考虑全局,只考虑子树内的贡献,设\(g_u\)表示以\(u\)为根的子树内,对\(u\)来说满足条件的点对数。对于\(u\)的儿子\(v\),对\(v\)来说合法那么对\(u\)来说也一定合法。因为......
  • openGauss学习笔记-207 openGauss 数据库运维-常见故障定位案例-btree 索引故障情况下
    openGauss学习笔记-207openGauss数据库运维-常见故障定位案例-btree索引故障情况下应对策略207.1btree索引故障情况下应对策略207.1.1问题现象偶发索引丢失错误,报错如下。ERROR:index'xxxx_index'containsunexpectedzeropage或ERROR:index'pg_xxxx_index'cont......
  • 《Visual Tree Convolutional Neural Network in Image Classification》阅读笔记
    论文标题《VisualTreeConvolutionalNeuralNetworkinImageClassification》图像分类中的视觉树卷积神经网络作者YuntaoLiu、YongDou、RuochunJin和PengQiao来自国防科技大学并行和分布式处理国家实验室初读摘要问题:在图像分类领域,随着深度学习的快速发展,卷......
  • centos 离线安装tree命令
    在线安装tree命令:yum-yinstalltree 但是在线包总是下载失败:RepositoryepelislistedmorethanonceintheconfigurationRepositoryepel-debuginfoislistedmorethanonceintheconfigurationRepositoryepel-sourceislistedmorethanonceinthecon......
  • Docker启动Nacos报错:Nacos Server did not start because dumpservice bean construct
    一、表象重启服务器之后Docker运行Nacos容器,启动成功,但是外网无法访问。查看了一下Nacos启动日志(dockerlogsnacos容器名)二、分析很明显是数据库配``置问题。。如果是数据库配置的问题,可以着重检查以下信息尤其是MySQL内网Host,查询方式见Docker安装Nacos三、解决我已......
  • Electron 解决 connect ETIMEDOUT 或 sill idealTree buildDeps
    参考https://blog.csdn.net/Johanna51/article/details/123360477https://www.electronjs.org/zh/docs/latest/tutorial/installationhttps://cloud.tencent.com/developer/article/1781066环境环境版本说明Windows10nodev20.11.0npm10.2.4Windows......
  • CodeForces 1010F Tree
    洛谷传送门CF传送门educational的。另一道类似的题是[ABC269Ex]Antichain(但是我还没写)。考虑令\(b_u=a_u-\sum\limits_{v\inson_u}a_v\)。那么\(\sum\limits_{i=1}^nb_i=a_1=x\),且\(\foralli\in[1,n],b_i\ge0\)。所以最后连通块内有\(y\)个点,那......
  • 「笔记」dsu on tree
    目录写在前面引入树上启发式合并代码复杂度分析例题CF570DTreeRequestsCF600ELomsatgelralCF1709EXORTree写在最后写在前面高产似那啥。还以为这东西是啥科技呃呃,原来是能证明复杂度的乱搞。所以重链剖分就是动态dsu(精神错乱引入dsuontree,即树上启发式合并。启发......