定义1:两棵树中的$x$和$y$对应当且仅当$x$到根的链与$y$到根的链同构
定义2:$x$和$y$的儿子状态相同当且仅当$x$与儿子所构成的树与$y$与儿子所构成的树同构
根据题中所给的定义,有以下两个的结论(观察可得,证明略):
结论1:对于两棵树$T_{1}$和$T_{2}$,$T_{1}->T_{2}$当且仅当对于$T_{1}$中的非叶子节点$x$和$T_{2}$中对应的点$y$,$x$和$y$的儿子状态相同
结论2:$grow(\mathscr{T})$几乎完备当且仅当不存在一棵树$T'$使得$\max h<h(T')$且$\forall 1\le i\le n,T_{i}\ne >T'$
这两个结论都比较显然,考虑继续发掘一些更有用的结论——
定义3:$T$为“链树”当且仅当其存在一条由根到某个叶子的链,使得树上任意一点到链上最近的点距离不超过1
结论3:对于树$T_{1}$和链树$T_{2}$,$T_{1}->T_{2}$当且仅当$T_{1}$为链树且$T_{2}$中所有深度不超过$h(T_{1})$的点所组成的树与$T_{1}$同构
(这个就是结论1通过观察得到的推论,即要求$T_{1}$是$T_{2}$的一个“前缀”(不太严谨),证明略)
结论4:$grow(\mathscr{T})$几乎完备当且仅当不存在一棵“链树”$T'$使得$\max h<h(T')$且$\forall 1\le i\le n,T_{i}\ne >T'$
证明:观察到仅将树改为了“链树”,由于“链树”的必要条件是树,结论2即必要性
考虑充分性,构造:对于一棵符合条件的树$T'$,将$T'$中最深的点(多个任选一个)到根的链作为$T''$的那条链,保留$T''$中所有到这条链距离为1的点(删去其他点),所构成的树显然为“链树”,接下去证明其符合条件
由于最长的链被保留,因此$\max h<h(T')=h(T'')$
由于$\forall 1\le i\le n,T_{i}\ne >T'$,必然有非叶子节点$x$使得$x$和$T'$中对应的点$y$儿子状态不同,令$a_{i}=y$
1.若$a_{i}$在链上(指“链树”的链),未改变$a_{i}$的儿子状态,仍然符合条件;
2.若$a_{i}$到链上最近的点距离为1,其儿子一定不被保留,则其为叶子节点而$x$为非叶子节点,儿子状态不同;
3.若$a_{i}$不被保留,取$a_{i}$为最近的被保留的祖先$z$,不妨设$a_{i}$在$z$的左子树中,由于$T_{i}$中存在$x$因此$z$在$T_{i}$中对应的点有左子树,而现在$z$的左子树必然为空(否则$z$应该取左儿子),即儿子状态不同
根据这两个结论,可以删去所有不为“链树”的树,然后暴力枚举链树:分为4类,链在(左/右)子树,有无(右/左)儿子,并递归链所在的子树
枚举时,维护一个$vector$表示当前仍然合法(即设枚举到的链树为$T'$,$T_{i}$合法当且仅当$T'->T_{i}$)的“链树”,同时若满足了$T_{i}->T'$(即当前决定儿子状态的点在$T_{i}$中对应的点为叶子)就停止枚举
考虑这一做法的时间复杂度:
当一棵“链树”最深的节点有兄弟,此时不妨视为两棵,这就保证每一棵链树仅被分入4类中的一类
时间复杂度即所有“链树”被划分的次数之和,而每一次划分可以看作“删除”掉当前正在处理的节点,显然这些删除不会重复,因此划分即删除的次数不超过$o(n)$,总复杂度即为$o(n)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 2000005
4 vector<int>v[N];
5 int V,T,t,n,m,r[N],ls[N],rs[N],tot[N];
6 bool pd(int k){
7 if (!tot[k])return 1;
8 if ((!tot[rs[k]])&&(pd(ls[k])))return 1;
9 if ((!tot[ls[k]])&&(pd(rs[k])))return 1;
10 return 0;
11 }
12 bool dfs(){
13 bool v0=0,v1=0,v2=0,v3=0;
14 for(int i=0;i<v[T].size();i++){
15 if (!tot[v[T][i]])return 0;
16 if ((ls[v[T][i]])&&(!tot[rs[v[T][i]]])&&(rs[v[T][i]]))v0=1;
17 if ((ls[v[T][i]])&&(!tot[ls[v[T][i]]])&&(ls[v[T][i]]))v1=1;
18 if ((rs[v[T][i]])&&(!tot[rs[v[T][i]]])&&(rs[v[T][i]]))v2=1;
19 if ((rs[v[T][i]])&&(!tot[ls[v[T][i]]])&&(ls[v[T][i]]))v3=1;
20 }
21 if ((!v0)||(!v1)||(!v2)||(!v3))return 1;
22 v[T+1].clear();
23 for(int i=0;i<v[T].size();i++)
24 if ((ls[v[T][i]])&&(!tot[rs[v[T][i]]])&&(rs[v[T][i]]))v[T+1].push_back(ls[v[T][i]]);
25 T++;
26 if (dfs())return 1;
27 T--;
28 v[T+1].clear();
29 for(int i=0;i<v[T].size();i++)
30 if ((ls[v[T][i]])&&(!tot[rs[v[T][i]]])&&(!rs[v[T][i]]))v[T+1].push_back(ls[v[T][i]]);
31 T++;
32 if (dfs())return 1;
33 T--;
34 v[T+1].clear();
35 for(int i=0;i<v[T].size();i++)
36 if ((rs[v[T][i]])&&(!tot[ls[v[T][i]]])&&(ls[v[T][i]]))v[T+1].push_back(rs[v[T][i]]);
37 T++;
38 if (dfs())return 1;
39 T--;
40 v[T+1].clear();
41 for(int i=0;i<v[T].size();i++)
42 if ((rs[v[T][i]])&&(!tot[ls[v[T][i]]])&&(!ls[v[T][i]]))v[T+1].push_back(rs[v[T][i]]);
43 T++;
44 if (dfs())return 1;
45 T--;
46 return 0;
47 }
48 int main(){
49 freopen("surreal.in","r",stdin);
50 freopen("surreal.out","w",stdout);
51 scanf("%d",&t);
52 while (t--){
53 scanf("%d",&m);
54 V=0;
55 for(int i=1;i<=m;i++){
56 scanf("%d",&n);
57 r[i]=V+1;
58 for(int j=1;j<=n;j++){
59 scanf("%d%d",&ls[j+V],&rs[j+V]);
60 if (ls[j+V])ls[j+V]+=V;
61 if (rs[j+V])rs[j+V]+=V;
62 tot[j+V]=(ls[j+V]>0)+(rs[j+V]>0);
63 }
64 V+=n;
65 if (!pd(r[i])){
66 V-=n;
67 i--;
68 m--;
69 }
70 }
71 T=0;
72 v[0].clear();
73 for(int i=1;i<=m;i++)v[0].push_back(r[i]);
74 if (dfs())printf("No\n");
75 else printf("Almost Complete\n");
76 }
77 return 0;
78 }

[loj3343]超现实树的更多相关文章

  1. [NOI2020] 超现实树

    我们定义链树为:在该树上的任意节点,左右子树大小的最小值小于2. 举个例子: 那么我们思考,链树显然可以在叶子节点任意替换成其他子树. 那么在主链上,我们可以做到生成任意深度大于主链长度的树. 反过来 ...

  2. 洛谷 P6776 - [NOI2020] 超现实树(找性质,神仙题)

    洛谷题面传送门 nb tea 一道! 首先考虑怎样入手分析这个看似非常不可做的问题.首先题目涉及高度无穷的树,根本枚举不了.不过我们冷静一下就会发现,如果我们记 \(mx=\max\limits_{i ...

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

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

  4. NOI2020网上同步赛 游记

    Day1 预计得分:\(32pts\)(我裂开了--) T1 美食家 表示考试的时候想到了关于矩阵快速幂的想法,甚至连分段后怎么处理都想好了,但是没有想到拆点,还有不知道怎么处理重边(这个考虑是多余的 ...

  5. NOI2020 同步赛划水记

    因为太菜了没去现场参加 NOI 就算去了估计也只能混个Fe(雾) "两天都会各有一道签到题,争取拿到70分.剩下的题每道题打30分暴力.每天130分,就能稳拿Ag了."--ls D ...

  6. WC2021 云划水记

    Day -38 - 2459208(2020.12.24) CCF 发公告了,线上举办 hopping. 刚看到还纠结了一会儿,但想想还是报了.虽说是去摸鱼,打打暴力分就走人.但毕竟有牌和没牌也是不一 ...

  7. Solution -「多校联训」朝鲜时蔬

    \(\mathcal{Description}\)   Link.   破案了,朝鲜时蔬 = 超现实树!(指写得像那什么一样的题面.   对于整数集 \(X\),定义其 好子集 为满足 \(Y\sub ...

  8. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  9. ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单

    前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...

随机推荐

  1. tomcat启动程序报错

    1.问题 23-Apr-2021 10:53:38.897 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.de ...

  2. 974.和可被K整除的子数组

    题目 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例: 输入:A = [4,5,0,-2,-3,1], K = 5 输出:7 解释: 有 7 个子数组满足其元 ...

  3. Noip模拟54 2021.9.16

    T1 选择 现在发现好多题目都是隐含的状压,不明面给到数据范围里,之凭借一句话 比如这道题就是按照题目里边给的儿子数量不超过$10$做状压,非常邪门 由于数据范围比较小,怎么暴力就怎么来 从叶子节点向 ...

  4. MyBatis源码分析(八):设计模式

    Mybatis中用到的设计模式 1. 建造者(Builder)模式: 表示一个类的构建与类的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一步一步创建一个复杂的对象,他只允许用户只通过指 ...

  5. 从0到1使用Kubernetes系列(五):Kubernetes Scheduling

    前述文章介绍了Kubernetes基本介绍,搭建Kubernetes集群所需要的工具,如何安装,如何搭建应用.本篇介绍怎么使用Kubernetes进行资源调度. Kubernetes作为一个容器编排调 ...

  6. Java I/O框架 - 总结概述

    总结 以下需要重点掌握: 字节流,以下读取结束全部返回-1 字节节点流-访问文件 FileInputStream/FileOutputStream 可以读取任意文件 可以复制图片 读取字符String ...

  7. arduino 使用 analogRead 读取不到数据,digitalRead 却可以正常读取

    项目场景: 最近在使用安信可的 ESP32S P14 引脚(ADC 16)读取一个电路状态的时候遇到一个问题,电路状态不是很稳定,在高电平的时候,会突然出现毫秒级的波动,出现短暂的低电平,造成设备状态 ...

  8. vs2015 MSB600 "inf2cat.ext"已退出,代码为2

    使用vs2015编译XDMA驱动过程中,报如下错误: vs2015 MSB600 "inf2cat.ext"已退出,代码为2 在使用Qt编译PCIE码表的过程中,出现C1038:无 ...

  9. 编译内核错误:Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373

    最近在编译一个新的rk sdk的时候,编译内核报错 CHK include/linux/version.h CHK include/generated/utsrelease.h make[1]: 'i ...

  10. zabbix 监控redis 挂掉自动重启 并发送企业微信

    1.创建redis监控项[配置]-[主机]-[监控项]-创建监控项,监控6379端口(注意关闭防火墙或者开启防火墙端口6379) redis配置文件设置允许任何地址监听: 添加监控项 2.创建redi ...