zoukankan      html  css  js  c++  java
  • [NOI2020]超现实树

    超现实树(Surreal)

    时隔 10 个月,我又来复盘此题啦 /se

    当时蒟蒻不会这道题,胡了个三树合并的做法,以为 GG 但发现竟然还有 40 pts /jy

    什么是三棵树合并?一个简单的例子:

    这是第 2 组样例。它的答案为 Almost Complete。对于更复杂的树,如果其它部分完全一样,三棵树分别是如上的结构,那么可以合并到一块,例如

    如果能合并成像右边一样是一个只包含根节点的树,它就是 Almost Complete,否则就是 No

    于是你开始信心满满地开始 rush 一份线性的带 Hash 的代码,当你开始一组组地跑样例时,发现 Case 5 WA 了!

    如果出题人按照开始只下发前 4 组样例,估计大多数错解选手就会跑路看 T1 或 T3,还好他是 Almost 良心 的(bushi),补发了两组!

    此时要反思为什么上面是错的。在第一幅图中:

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(} e{ m grow}()())

    发现两者不完全等价!我们尝试修正该方法。我们使用红色的节点来 特殊化 被合并的节点,也就是像这样

    按照这样,我们重新合并图二中的树

    但是接下来又要纠结了:带有特殊节点的合并是什么样的?我们不难遐想到有如下多种可能

    合并的组合突然间多了很多。我们试图来讨论。但在讨论前,我们想要弄明白 特殊节点 的含义,就目前来看,它表示:除了特殊节点自身一个节点的树无法生成,其它任意子树皆可被生成

    首先,我们要排除上图中的 (1,4)(最右上角的),这种情况不具有意义。它表明:左右子树同时不能为自身。而在这样的限制条件下,无法产生的树的集合大小为 无限大(令左儿子为自身,右儿子形态任意),即使加强限制使得集合大小有限,该限制 不强于 其它七种情况,换句话说它是 没有用的。想避免此种情况,也就是说红色节点的个数必须 (le 1)

    接着,我们来一一讨论。对于对称的情况我们可以转化,有用的情形总结如下:

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(~+~)(})

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(~+~)(~+~)(})

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(~+~)(~+~)(})

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(~+~)(~+~)(})

    ({ m grow}()()+{ m grow}()()+{ m grow}()()={ m grow}()()setminus{)(~+~)(~+~)(~+~)(})

    三角形表示该点构成的子树形态任意。

    发现第 2、3、5 种情况下,不可生成的部分中有一种情况,它可以拓展出无数种树。这也直接指出三棵树合并的错误之处了。这时发现第 5 组中:

    ({)(}+{ m grow}()()={ m grow}()()setminus{)(})

    利用右边的红点,可以把右边的子树“封死”,而且不难证明该条件是必要的。这样不可生成的集合大小就是有限的了!

    于是能推导出四棵树合并:

    ({ m grow}()()+{ m grow}()()+{ m grow}()(}+{ m grow}()()={ m grow}()()setminus{)(~+~)(~+~)(~+~)(})

    可是右边的东西还是有点复杂?不过发现:等式右边都满足,由根生长的树,却不能在等式左边生长出来的数目是 有限的。如果拓宽 特殊点 的定义:特殊点所在的子树内对于数量 有限 的拓展下无法生成,除此之外其它基于原树拓展的部分均可生成。

    不难发现上述合并法则依然成立!

    为了统一,我们甚至可以

    这样就可以将四棵树合并的策略适用于任何情况了。注意初始情况下 特殊节点 不可生成的树为空,但只要合并过,就一定非空,可以证明这样转换不会出现超出该合并法则的情况。

    于是修正最开始三棵树合并的代码,使用 Hash 跑四棵树合并,即可通过本题。期望复杂度 (mathcal O(n))

    这道题还要用 Hash?Too weak!这里还有没挖掘的性质,可以大幅降低代码实现难度。

    对于第二幅图中的树,它对答案是不起作用的,因为若干次合并后会出现这样的情况:

    这与前面的推论矛盾了。什么样子的树在合并的过程中不会出现这样的情况?稍加思考可以发现,如果一个儿子合并了,另一个儿子不能合并。该种类树的形态:有一条主链,然后链上的每一个非叶子节点要么仅仅有一个节点,要么没有节点。

    这跟官方题解中 树枝 的定义一致。官方题解中说:对于所有深度为 MAX_DEP 的树枝若均能被生成,则其 Almost Complete。而上面的合并,刚好符合这样的要求。

    于是删掉无用的树之后,我们可以递归合并。这样就大幅简化代码了。复杂度仍然可以做到 (mathcal O(n))

    #include <bits/stdc++.h>
    #define pb push_back
    #define x first
    #define y second
    using std::vector; using std::pair;
    const int N = 2e6 + 5;
    int T, n, m;
    vector<int> lc[N], rc[N];
    vector<pair<int, int>> tmp;
    int dfs(vector<pair<int, int>> A) {
    	vector<pair<int, int>> A0, A1, A2, A3;
    	if (!A.size()) return 0;
    	for (auto u : A) {
    		int x = lc[u.x][u.y], y = rc[u.x][u.y];
    		if (!x && !y) return 1;
    		if (!x || !y) x ? A0.pb({u.x, x}) : A1.pb({u.x, y});
    		else {
    			if (!lc[u.x][y] && !rc[u.x][y]) A2.pb({u.x, x});
    			if (!lc[u.x][x] && !rc[u.x][x]) A3.pb({u.x, y});
    		}
    	}
    	return dfs(A0) && dfs(A1) && dfs(A2) && dfs(A3);
    }
    void solve() {
    	scanf("%d", &n); tmp.clear();
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &m);
    		lc[i].resize(m + 1), rc[i].resize(m + 1);
    		for (int j = 1; j <= m; j++) scanf("%d%d", &lc[i][j], &rc[i][j]);
    		tmp.pb({i, 1});
    	}
    	puts(dfs(tmp) ? "Almost Complete" : "No");
    }
    int main() {
    	scanf("%d", &T);
    	while (T--) solve();
    	return 0;
    }
    
  • 相关阅读:
    Educational Codeforces Round 83 --- F. AND Segments
    Educational Codeforces Round 83 --- G. Autocompletion
    SEERC 2019 A.Max or Min
    2019-2020 ICPC Southwestern European Regional Programming Contest(Gym 102501)
    Educational Codeforces Round 78 --- F. Cards
    今天我学习了一门全新的语言
    codeforces 1323D 题解(数学)
    Educational Codeforces Round 80 (Div. 2) 题解 1288A 1288B 1288C 1288D 1288E
    Educational Codeforces Round 81 (Div. 2) 题解 1295A 1295B 1295C 1295D 1295E 1295F
    Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F
  • 原文地址:https://www.cnblogs.com/ac-evil/p/14897984.html
Copyright © 2011-2022 走看看