洛谷题面传送门

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. java调用js脚本语言

    在我们开发的过程中,可能有这么一种情况,在java中需要取调用js方法完成一些事情.那么什么时候可能出现这种情况呢.比如我们使用爬虫模拟登录别的网站,但有些网站前台使用js对密码进行了加密处理,那么就 ...

  2. Noip模拟42 2021.8.17

    T1 卷 一看跟没有上司的舞会一样,直接敲了然后试个自己造的样例对了就跑了... 然而把它想简单了,乘积取模,还能比大小吗????? 显然不能 所以直接让对数的加和跟着$dp$直接一起跑,比大小的都用 ...

  3. 「刷题」THUPC泛做

    刷了一下,写一下. T1. 天天爱射击 可以这样想. 我们二分一下每一块木板在什么时刻被击碎. 然后直接用主席树维护的话是\(O(nlog^2n)\)的. 会\(T\),而且是一分不给那种... 那么 ...

  4. Vue脚手架最新版本安装使用

    现在很多的插件如Vant 这类的样式框架,都去兼容了Vue的3.0版本,所以我总结一下如何去简单的搭建一个Vue3.0的框架 开始 一,如何安装 在这里说明一下,Vue脚手架版本,和Vue版本是两个东 ...

  5. flyway的使用

    1.使用它之前先要了解一些概念: 版本:对数据库的每一次变更可称为一个版本. 迁移:Flyway把数据库结构从一个版本更新到另一个版本叫做迁移. 可用的迁移:Flyway的文件系统识别出来的迁移版本. ...

  6. redis 的主从模式哨兵模式

    原理理解 1,哨兵的作用就是检测redis主服务的状态,如果主服务器挂了,从服务就自动切换为主服务器,变为master.哨兵是一个独立的进程,作为进程,它会独立运行.其原理是哨兵通过发送命令,等待Re ...

  7. mysql 导入sql文件

    navicat 工具导入 1.连接数据库后,右键选择导入sql文件 2.选择sql文件,开始导入 4.过程图 5.结果图

  8. windows 系统文件夹挂载到 Linux 系统,拷贝(发送)文件到 windows 系统,实现异地备份

    1.在windows 系统上配置好共享文件夹,用来接收Linux 系统的文件   注意:关闭windows 系统防火墙,或者添加进出站规则 2.在Linux 系统中,创建需要拷贝的文件目录 #mkdi ...

  9. Spring源码学习之容器的基本实现(一)

    前言 最近学习了<<Spring源码深度解析>>受益匪浅,本博客是对学习内容的一个总结.分享,方便日后自己复习或与一同学习的小伙伴一起探讨之用. 建议与源码配合使用,效果更嘉, ...

  10. IP基础 & 子网划分 & 路由寻址

    IP地址详解 IP地址概念 就像用身份证号码来区别毎个人一样,为了区别 网上的每台计算机,我们给因特网上的每一台计算机一个唯一的编号 ,我们把它称为IP地址 IP地址就是一个唯一标识 ,是一段网络编码 ...