洛谷 P6776 - [NOI2020] 超现实树(找性质,神仙题)
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\),有四种可能:
- \(p_i\) 的左儿子在链树主链上,\(p_i\) 没有右儿子
- \(p_i\) 的右儿子在链树主链上,\(p_i\) 没有左儿子
- \(p_i\) 的左儿子在链树主链上,\(p_i\) 右儿子为叶子节点
- \(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] 超现实树(找性质,神仙题)的更多相关文章
- Solution -「NOI 2020」「洛谷 P6776」超现实树
\(\mathcal{Description}\) Link. 对于非空二叉树 \(T\),定义 \(\operatorname{grow}(T)\) 为所有能通过若干次"替换 \( ...
- 【BZOJ2830/洛谷3830】随机树(动态规划)
[BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- 洛谷P3655 差分数组 树状数组
题目链接:https://www.luogu.org/problemnew/show/P3655 不一定对,仅供参考,不喜勿喷,不喜勿喷. 先copy洛谷P3368 [模板]树状数组 2 题解里面一位 ...
- 洛谷:P1087 FBI树 P1030 求先序排列 P1305 新二叉树
至于为啥把这三个题放到一起,大概是因为洛谷的试炼场吧,三道树的水题,首先要理解 先序中序后序遍历方法. fbi树由于数量小,在递归每个区间时,暴力跑一遍区间里的数,看看是否有0和1.至于递归的方法,二 ...
- 【洛谷 5002】专心OI - 找祖先 (树上计数)
专心OI - 找祖先 题目背景 \(Imakf\)是一个小蒟蒻,他最近刚学了\(LCA\),他在手机\(APP\)里看到一个游戏也叫做\(LCA\)就下载了下来. 题目描述 这个游戏会给出你一棵树,这 ...
- Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)
题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...
- BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
随机推荐
- Java:TreeMap类小记
Java:TreeMap类小记 对 Java 中的 TreeMap类,做一个微不足道的小小小小记 概述 前言:之前已经小小分析了一波 HashMap类.HashTable类.ConcurrentHas ...
- ssh后门反向代理实现内网穿透
如图所示,内网主机ginger 无公网IP地址,防火墙只允许ginger连接blackbox.example.com主机 假如你是ginger的管理员root,你想要用tech主机连接ginger主机 ...
- MiniFly四轴飞行器之部分系统及电源分析
最近硬件四轴很火,了解了很久,还是选择了MiniFly,主要还是资料多,后边可以有人讨论,不像很多就是建了个群,研究问题还是在论坛方便很多. 四轴终于拿到手,功能很强大,主要是还支持二次开发,可以研究 ...
- Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler
Netty 使用异步事件驱动(Asynchronous Event-Driven)的应用程序范式,因此数据处理的管道(ChannelPipeLine)是经过处理程序(ChannelHandler)的事 ...
- [转]浅谈电路设计中应用DDR3处理缓存问题
本文转自:浅谈电路设计中应用DDR3处理缓存问题_若海人生的专栏-CSDN博客 DDR系列SDRAM存储芯片的高速率.高集成度和低成本使其理所当然成为存储芯片中的一霸.在PC和消费电子领域自是如此,它 ...
- 2021CCPC河南省赛(部分代码待更)
最终A了8道题, 喜提一金, 也是在意料之中. 第一次三个队友集中在一起打比赛, 也体验了一下线下的氛围, 还是比较赞的, 自己也不是说毫无作用, 帮助团队做了几道题, 还是挺满意的. 1002 em ...
- 【java+selenium3】自动化cookie操作+图形验证码处理 (十五)
一.cookie操作 1.获取浏览器所有的cookie import java.util.Set; import org.openqa.selenium.Cookie; //获取浏览器所有的cooki ...
- Pytorch中stack()方法的理解
Torch.stack() 1. 概念 在一个新的维度上连接一个张量序列 2. 参数 tensors (sequence)需要连接的张量序列 dim (int)在第dim个维度上连接 注意输入的张量s ...
- 【死磕 NIO】— Proactor模式是什么?很牛逼吗?
大家好,我是大明哥. 上篇文章我们分析了高性能 IO模型Reactor模式,了解了什么是Reactor 模式以及它的三种常见的模式,这篇文章,大明再介绍另外一种高性能IO模型: Proactor. 为 ...
- dart系列之:dart语言中的内置类型
目录 简介 Null 数字 字符串 布尔值 列表 set和map 简介 和所有的编程语言一样,dart有他内置的语言类型,这些内置类型都继承自Object,当然这些内置类型是dart语言的基础,只有掌 ...