Description
Input
第一行包含一个正整数 m,代表操作数。
接下来 m 行,每行可能有以下形式:
1 s 代表将数字串 s 加入信息集中
2 s 代表询问数字串 s 是否在信息集中
3 a b 代表使数字串 a 和 b 互相纠缠
Output
对于每一个 2 操作,如果询问串不在集合中,请输出一行一个整数 0,否则输出一行一个整 数 1。
Sample Input
11
1 123
2 123
2 0
3 12 13
1 124
2 133
2 134
2 13
3 1 11
2 111
2 11111111111111111111111124
Sample Output
1
0
1
1
0
0
1
Data Constraint
题解
这道题是一道十分新颖的题目,吼题。
然而新颖到读不懂题。
题意:插入就是在原串中加入数字串。
查询的时候是查询原串中有无整个数字串。注意:不是子串。
主要是纠缠在一起不好理解。其实就是在原来的数字串中,有一个A串,和一个B串。如果A串后面连着一个C串,那么B串后面也要加入一个C串。反之,B串后面连着个D串,那么A串也要连上。
这样理解纠缠就比较好了吗?
当然,如果A串或B串不在原串中,要特别地加入。
注意这些题意小细节后,就可以很好地做了。
我们看看没有纠缠操作,显然可以建一颗trie,然后再每个数字串末尾打一个flag标记表示这个数字串是否合法。
直接查询即可。
然而只能得10分。良心出题人
那么我们就看看纠缠操作。
由于这个操作很像是把A串与B串在trie上的子树分成同样的两份,而这样空间很大。那么我们反过来考虑。能否把A串与B串合并呢?
论trie怎么合并
其实不用怎么复杂,只需要用并查集维护即可。
首先,我们在trie上找到A串与B串对应的位置,然后合并这两个点。设A对应点为x1,B对应点为x2。
我们令B串合并到A串上去。
那么我们就直接把x2的祖先连到x1的祖先。
然后,我们寻找儿子,如果x1有一个儿子而x2没有这个对应的儿子,那么就在x2这里连一条trie上的边到x1的这个儿子。反之亦然。
如果两个都有对应的儿子,那么就递归下去合并。
还有就是如果x1与x2要在并查集上连边时,如果有flag标记,那么就要传递一下。
这样就合并完了。
最后,我们在查询,插入,纠缠时,都要在走一条字母边时,getfather一下,这样才能保证最终走到的点是与其他与之合并的点,然后才能够符合题意,每次都找纠缠的点。
然而,题解很lj,虽然给了个小数据可以调一调,然而这个小数据实际上很鸡肋。
输入
5
1 00
1 11
3 0 10
3 0 1
2 000001
输出
1