• 树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(1le nle 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
    ",tot);
    39     return 0;
    40 
    41 }
    View Code
  • 相关阅读:
    HDU 1402 A * B Problem Plus FFT
    HDU 4609 3-idiots FFT
    Hihocoder #1527 : 快速乘法 DP
    Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo DP+矩阵快速幂加速
    Codeforces 8VC Venture Cup 2016
    FFT做题记录
    Hackrank Candies DP
    git submodule update --init --recursive
    慢慢长大
    protobuf
  • 原文地址:https://www.cnblogs.com/qq-1585047819/p/12078484.html
Copyright © 2020-2023  润新知