树hash求不同子树得数量

链接:https://ac.nowcoder.com/acm/contest/2763/H
来源:牛客网

二叉查找树
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

树神精通各种树,这其中自然包括二叉查找树

立志成为小树神的cjc正在向树神学习一手二叉查找树,他问了这么一道题:将一些数顺序插入建立二叉查找树,有多少种形状不同的子树?

如果你精通数据结构,可以跳过以下内容。

二叉查找树,也称为二叉搜索树、有序二叉树或排序二叉树。它是一种具有如下性质的二叉树形结构
1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值
2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值
3. 任意节点的左、右子树也分别为二叉查找树
4. 没有值相等的节点。
一列数按顺序插入二叉查找树的构造方法如下
1. 若当前树为空,则加入节点,值为当前数的值,该节点视为根节点
2. 若当前树不为空,则从根节点开始向下遍历。若当前数的值小于正在遍历的节点值,则向左子节点遍历,否则向右子节点遍历,直到不存在对应的子节点为止,在该处建立新的节点,值为当前数的值。

其中,树形结构在计算机学科中,一般指一种看起来像一棵倒挂的树的层次结构,如图1

树形结构具有如下性质

1. 每个节点都只有有限个子节点或无子节点
    1.1 对于二叉树,每个节点都只有0~2个子节点
2. 没有父节点的节点称为根节点
3. 每一个非根节点有且只有一个父节点
4. 除了根节点外,每个子节点可以分为多个不相交的子树
5. 树里面没有环路

其中,子树指的是树形结构中,任意节点及其所有后代导出的子结构。二叉树左子树就是以当前节点看,它的左子节点那一分支的子树,该子树以当前节点左子节点为根。右子树就是以当前节点看,它的右子节点那一分支的子树,该子树以当前节点右子节点为根。

对于两颗二叉树子树,若忽略节点上的值,得到相同的树形结构,则认为这两颗二叉树子树形状相同。


输入描述:

第一行输入一个正整数n(1≤n≤1000)n(1\le n\le 1000)n(1n1000),代表要插入的数的个数

第二行输入n个正整数,一个1~n的排列,即1~n中每个数仅出现一次。

输出描述:

按输入顺序将数依次插入二叉查找树,输出这颗二叉查找树互不相同的子树个数。
示例1

输入

复制
4
1 2 3 4

输出

复制
4
示例2

输入

复制
4
1 3 4 2

输出

复制
3

备注:

对于样例一,建立的二叉查找树如图t1

不同形状的子树分别为t1t1bt1ct1d

对于样例二,建立的二叉查找树如图

不同形状的子树分别为t2t2bt2c

t2ct1d相同

 

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const int maxn=1005;
 6 int L[maxn],R[maxn];
 7 int arr[maxn];
 8 int n,tot;
 9 map<pair<int,int>,int> ma;
10 
11 void Find(int u,int v){
12     if(arr[u]<arr[v]){
13         if(R[u]==-1) R[u]=v;
14         else Find(R[u],v);
15     }
16     else{
17         if(L[u]==-1) L[u]=v;
18         else Find(L[u],v);
19     }
20 }
21 
22 int dfs(int ee){
23     int l=-1,r=-1;
24     if(L[ee]!=-1) l=dfs(L[ee]);
25     if(R[ee]!=-1) r=dfs(R[ee]);
26     if(!ma.count({l,r})) ma[{l,r}]=++tot;
27     return ma[{l,r}];
28 }
29 
30 int main(){
31     memset(L,-1,sizeof(L)),memset(R,-1,sizeof(R));
32     scanf("%d",&n);
33     for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
34     for(int i=2;i<=n;i++){
35         Find(1,i);
36     }
37     dfs(1);
38     printf("%d\n",tot);
39     return 0;
40 
41 }
View Code

 

posted @ 2019-12-21 22:23  厂长在线养猪  Views(311)  Comments(0Edit  收藏  举报