洛谷题面传送门

nb tea 一道!

首先考虑怎样入手分析这个看似非常不可做的问题。首先题目涉及高度无穷的树,根本枚举不了。不过我们冷静一下就会发现,如果我们记 \(mx=\max\limits_{i=1}^{n}\text{dep}(T_i)\),那么由于初始树的集合中不存在深度 \(>mx\) 的树,因此所有可以生成的深度 \(>mx\) 的树都经过了生长操作,也是说:

Observation \(1\). 对于某个深度 \(d>mx\),存在深度为 \(d\) 的树不能通过生长得到的充要条件是存在深度为 \(d-1\) 的树不能通过生长得到。

证明大概就反证一下?假设深度为 \(d-1\) 的树都能生长得到,那么对于一棵深度为 \(d\) 的树显然可以通过砍掉它所有叶子得到的深度为 \(d-1\) 的树生长得到。而对于一棵不能生长得到的深度为 \(d-1\) 的树,将它深度为 \(d-1\) 的叶子向下延伸一格,得到的深度为 \(d\) 的树也无法通过生长操作得到,又 \(d>mx\),因此得到的深度为 \(d\) 的树也不在初始的树集合中,也无法得到。

因此我们只用检验是否存在深度为 \(mx\) 的树不能通过生长操作得到即可。

那么我们是否究竟需要把所有深度为 \(mx\) 的树都检验一遍呢?

Observation \(2\). 所有深度为 \(mx\) 的树都能够通过生长操作得到,等价于所有深度为 \(mx\) 的链树(caterpillar)都能够通过生长操作得到,其中链树的定义是,存在一条根节点到某个叶子节点的路径,满足其它点到这条路径的距离都 \(\le 1\)。

显然如果所有链树都能够通过生长操作得到,那么对于一棵深度为 \(mx\) 的树,我们找出根节点到其任意一个深度为 \(mx\) 的叶子的路径,然后对于路径上每个点 \(p_i\),我们找出它不在这条路径上的儿子(显然这个儿子是唯一的),如果存在我们就把它的子树缩成一个点,那么这个树就可以由缩得的这个链树生长得到。而如果存在某个链树无法通过生长得到,那……显然由于链树 \(\in\) 树,必然存在某个深度为 \(mx\) 的树无法通过生长得到。

Observation \(3\). 非链树无法生成链树

显然,由于生长操作不支持删点,因此如果存在某个点,满足其左右儿子子树大小较小值 \(>1\),那该节点不论怎么生长,其左右儿子子树大小较小值永远 \(>1\)。

Observation \(4\). 对于输入中的树的集合,我们只用保留其中是链树的树

由于非链树不能生成链树,所以我们保留它们也没有用。

Observation \(5\). 一棵深度为 \(d\) 的链树可以压缩成一个长度为 \(d\) 的四进制树

对于一棵深度为 \(d\) 的链树 \(T\),考虑其主链 \(C\),那么对于主链上任意一个点 \(p_i\),有四种可能:

  1. \(p_i\) 的左儿子在链树主链上,\(p_i\) 没有右儿子
  2. \(p_i\) 的右儿子在链树主链上,\(p_i\) 没有左儿子
  3. \(p_i\) 的左儿子在链树主链上,\(p_i\) 右儿子为叶子节点
  4. \(p_i\) 的右儿子在链树主链上,\(p_i\) 左儿子为叶子节点

注意,对于链树主链上倒数第二个节点,如果它的两个儿子都是叶子节点,此时该链树就有两个叶子节点,此时也就对应有两种压缩方法。

那么我们的任务即为查看是否所有这样长度为 \(mx\) 的四进制数都能够通过某种方式得到。

我们考虑对于一棵链树,按照如下方式将其压缩成一个或两个四进制数并将其对应到一个四叉树上,那么四叉树上的某个节点,如果其子树中只有有限棵树无法被生成,那么必定有:

  • 该点在某一棵链树中为叶子节点,此时它可以替换为任何四进制数。
  • 该点拥有全部四个儿子,且四个儿子代表的子树中都仅有有限棵树无法被生成。

否则如果它儿子个数 \(<4\),并且它不在任何一棵链树中是叶子节点,那么它缺失的儿子对应的链树就无法被表示出来。

按照如上方式建出四叉树,然后对四叉树进行一遍 DFS 即可求出答案。

时间复杂度 \(\mathcal O(n)\)

希望今年 NOI D2 不要出这么阴间的题(

不过话说回来今年 D1 这么良心估计 D2 得做好被虐的准备了/qiao

const int MAXN=2e6;
int ch[MAXN+5][2],ch_[MAXN+5][4],siz[MAXN+5],ncnt,rt,ok[MAXN+5];
bool checkchain(int x){
siz[x]=1;
for(int i=0;i<2;i++) if(ch[x][i]){
if(!checkchain(ch[x][i])) return 0;
siz[x]+=siz[ch[x][i]];
} return !(ch[x][0]&&ch[x][1]&&min(siz[ch[x][0]],siz[ch[x][1]])>1);
}
void insert(int &x,int y){
if(!x) x=++ncnt;
// printf("%d %d\n",x,y);
if(!ch[y][0]&&!ch[y][1]) return ok[x]=1,void();
if(ch[y][0]&&!ch[y][1]) return insert(ch_[x][0],ch[y][0]),void();
if(!ch[y][0]&&ch[y][1]) return insert(ch_[x][1],ch[y][1]),void();
if(siz[ch[y][0]]==1) insert(ch_[x][2],ch[y][1]);
if(siz[ch[y][1]]==1) insert(ch_[x][3],ch[y][0]);
}
bool dfs(int x){
if(ok[x]) return 1;if(!x) return 0;ok[x]=1;
for(int i=0;i<4;i++) ok[x]&=dfs(ch_[x][i]);return ok[x];
}
void solve(){
int N;scanf("%d",&N);ncnt=rt=0;
memset(ch_,0,sizeof(ch_));memset(ok,0,sizeof(ok));
while(N--){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&ch[i][0],&ch[i][1]);
if(!checkchain(1)) continue;insert(rt,1);
} printf("%s\n",dfs(rt)?"Almost Complete":"No");
}
int main(){
// freopen("surreal.in","r",stdin);freopen("surreal.out","w",stdout);
int qu;scanf("%d",&qu);while(qu--) solve();
return 0;
}

洛谷 P6776 - [NOI2020] 超现实树(找性质,神仙题)的更多相关文章

  1. Solution -「NOI 2020」「洛谷 P6776」超现实树

    \(\mathcal{Description}\)   Link.   对于非空二叉树 \(T\),定义 \(\operatorname{grow}(T)\) 为所有能通过若干次"替换 \( ...

  2. 【BZOJ2830/洛谷3830】随机树(动态规划)

    [BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...

  3. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  4. 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)

    洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...

  5. 洛谷P3655 差分数组 树状数组

    题目链接:https://www.luogu.org/problemnew/show/P3655 不一定对,仅供参考,不喜勿喷,不喜勿喷. 先copy洛谷P3368 [模板]树状数组 2 题解里面一位 ...

  6. 洛谷:P1087 FBI树 P1030 求先序排列 P1305 新二叉树

    至于为啥把这三个题放到一起,大概是因为洛谷的试炼场吧,三道树的水题,首先要理解 先序中序后序遍历方法. fbi树由于数量小,在递归每个区间时,暴力跑一遍区间里的数,看看是否有0和1.至于递归的方法,二 ...

  7. 【洛谷 5002】专心OI - 找祖先 (树上计数)

    专心OI - 找祖先 题目背景 \(Imakf\)是一个小蒟蒻,他最近刚学了\(LCA\),他在手机\(APP\)里看到一个游戏也叫做\(LCA\)就下载了下来. 题目描述 这个游戏会给出你一棵树,这 ...

  8. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  9. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

随机推荐

  1. 3.4 Common Principles 通用原则

    3.4 Common Principles 通用原则 Before going into details, let's see some overall DDD principles; 在讨论细节之前 ...

  2. 【Spring】IoC容器 - 依赖查找

    前言 上一篇文章已经学习了[IoC的主要实现策略]有2种: 1.依赖查找 2.依赖注入 这里稍加详细的介绍一下依赖查找 1.依赖查找的方式 依赖查找的方式可以以多种维度来划分: 1.按名称/类型/注解 ...

  3. 网络通信IO的演变过程(一)(一个门外汉的理解)

    以前从来不懂IO的底层,只知道一个大概,就是输入输出的管道怼到一起,然后就可以传输数据了. 最近看了周志垒老师的公开课后,醍醐灌顶. 所以做一个简单的记录. 0 计算机组成原理相关 0.1. 计算机的 ...

  4. 【UE4 调试】C++ 几种编译方法和小技巧

    编译方法 Visual Studio 2019 编译 默认编译 UnrealVS 快速编译 Editor 编译 一般 vs 编译完后,Editor会跟着热编译(有声音) 如果发现编译后代码没更新到Ed ...

  5. OO第四单元作业总结及课程总结

    一.本单元作业架构设计 1.第一次作业 本单元首次接触到UML以及相关概念,在面对第一次作业时首先花了很大功夫去阅读官方接口中各种UmlElement的代码,才理解了输入的模型元素中各属性的含义.总的 ...

  6. seata整合nacos完成分布式的部署

    seata整合nacos完成分布式的部署 一.背景 二.部署机器 三.部署步骤 1.在seata上创建命名空间 2.下载对应版本的seata 3.单机启动 1.修改seata配置文件 1.修改注册中心 ...

  7. 实验5:开源控制器实践——POX

    一.实验目的 1.能够理解 POX 控制器的工作原理: 2.通过验证POX的forwarding.hub和forwarding.l2_learning模块,初步掌握POX控制器的使用方法: 3.能够运 ...

  8. IdentityServer4 负载均衡配置

    在不用到负载之前,一切都很好,但是部署多个实例之后,问题挺多的:session问题.令牌签发后的校验问题. 在此之前,先自查官方文档:Deployment - IdentityServer4 1.0. ...

  9. (类)Program1.1

    1 class MyClass: 2 3 i = 12345 4 5 def __init__(self): 6 self.data = "WOOWOWOWO" 7 8 def f ...

  10. 全志Tina_dolphin播放音视频裸流(h264,pcm)验证

    最近在验证tina对裸流音视频的支持,主要指h264视频裸流及pcm音频裸流. 在原始sdk中有针对很多video和audio类型的parser,但就是没有找到pcm和h264的parser,所以需要 ...