洛谷题面传送门

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. ES2020新特性记录

    1.可选链操作符 // oldlet ret = obj && obj.first && obj.first.second// newlet ret = obj?.fi ...

  2. FastAPI 学习之路(四十二)定制返回Response

    我们想要在接口中返回xml格式的内容,我们应该如何实现呢. from fastapi import FastAPI,Response @app.get("/legacy/") de ...

  3. px,dp sp是像素、尺寸、尺寸

    px:即像素,1px代表屏幕上一个物理的像素点:px单位不被建议使用,因为同样100px的图片,在不同手机上显示的实际大小可能不同,如下图所示(图片来自android developer guide, ...

  4. [软工顶级理解组] Beta阶段团队贡献分评分

    贡献分评分依据 下述表格适用于前端.后端.爬虫开发者的评分,在此基础上进行增减. 类别 程度 加减分 准时性 提前完成 +0 按时完成 +0 延后完成,迟交时间一天内或未延误进度 -2 延后完成,迟交 ...

  5. OO--第三单元规格化设计 博客作业

    OO--第三单元规格化设计 博客作业 前言 第三单元,我们以JML为基础,先后完成了 PathContainer -> Graph -> RailwaySystem 这是一个递进的过程,代 ...

  6. FastAPI 学习之路(三十四)数据库多表操作

    之前我们分享的是基于单个的数据库表的操作,我们在设计数据库的时候也设计了跨表,我们可以看下数据库的设计. class User(Base): __tablename__ = "users&q ...

  7. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

  8. Machine learning (6-Logistic Regression)

    1.Classification However, 2.Hypothesis Representation Python code: import numpy as np def sigmoid(z) ...

  9. 用python检查矩阵的计算

    鉴于最近复习线性代数计算量较大,且1800答案常常忽略一些逆阵.行列式的计算答案,故用Python写出矩阵的简单计算程序,便于检查出错的步骤. 1.行列式 可自行更改阶数 from numpy imp ...

  10. Luogu P1196 [NOI2002]银河英雄传说 | 并查集

    题目链接 并查集,具体看注释. #include<iostream> #include<cstdio> #include<cmath> using namespac ...