zoukankan      html  css  js  c++  java
  • jzoj 3957 鸡腿の花园

    Description

    【故事の背景】
     
    鸡腿是CZYZ的著名DS,他为了树立高富帅的伟大形象决定暑假去张江大学学习(游玩)。张江大学自古以来就是充满了各种程序猿的地方,这里的花园自然也是十分奇葩,充满了符合程序猿口味的东西。鸡腿来到张江,自己也打理了一个小花园,小花园里种满了二叉树!
     
    二叉树是什么呢,一棵树,除了根节点之外每个点都有父亲节点,同时每个节点只会有0个、1个或者2个孩子的树。
     
    【问题の描述】
     
    鸡腿在种树的过程中发现有两棵二叉树长的骨骼清奇,是树中极品。为了仔细研究这两颗树,鸡腿决定要研究一下这两棵树的共同点。鸡腿想让你帮他算一算,这两棵树上有多少相同的子树。
    相同的子树指树A中的子树a和树B中的子树b完全相同,二叉树的相同定义为树上总节点个数相同,根节点孩子数相同,而且两棵子树分别相同。当然,孩子节点是有先后顺序的!

    Data Constraint

    对于20%的数据1 ≤ N,M ≤ 100;
    对于40%的数据 1 ≤ N,M ≤ 5,000;
    对于100%的数据 1 ≤ N,M ≤ 100,000。
     

    Sol 

     Hash大法好。

     Hash函数随便写,怎么奇怪怎么来。

    #include<bits/stdc++.h>
    #define ull unsigned long long
    using namespace std;
    struct Hax{
        #define HaN 1234007
        int hea[HaN],net[HaN],fall[HaN],tot;
        ull key[HaN];
        int &get(ull _h){
            static int h;
            h=_h%HaN;
            for (int i=hea[h];i;i=net[i])
             if (key[i]==_h) return fall[i];
            key[++tot]=_h; net[tot]=hea[h]; hea[h]=tot;
            return fall[tot];
        }
        int Get(ull _h){
            static int h;
            h=_h%HaN;
            for (int i=hea[h];i;i=net[i])
             if (key[i]==_h) return fall[i];
            key[++tot]=_h; net[tot]=hea[h]; hea[h]=tot;
            return fall[tot];
        }
    }f;
    #define N 2000007
    #define lx 23333
    #define rx 998443
    int siz[N],ch[N][2],n,m;
    ull ha[N],ans;
    void dfs(int x){
        if (ch[x][0]) dfs(ch[x][0]);
        if (ch[x][1]) dfs(ch[x][1]);
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
        ha[x]=ha[ch[x][0]]*ha[ch[x][0]]*lx+ha[ch[x][1]]*rx+siz[x]^siz[ch[x][1]];
        f.get(ha[x])++;
    }
    void Dfs(int x){
        if (ch[x][0]) Dfs(ch[x][0]);
        if (ch[x][1]) Dfs(ch[x][1]);
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
        ha[x]=ha[ch[x][0]]*ha[ch[x][0]]*lx+ha[ch[x][1]]*rx+siz[x]^siz[ch[x][1]];
        ans+=f.Get(ha[x]);
    }
    signed main () {
        freopen("1.in","r",stdin);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) {
         scanf("%d%d",ch[i],ch[i]+1); 
         if (ch[i][0]==-1) ch[i][0]=0;
         if (ch[i][1]==-1) ch[i][1]=0;
         }
        dfs(1);
        memset(ch,0,sizeof ch);
        memset(siz,0,sizeof siz);
        memset(ha,0,sizeof ha);
        for (int i=1;i<=m;i++) {
         scanf("%d%d",ch[i],ch[i]+1); 
         if (ch[i][0]==-1) ch[i][0]=0;
         if (ch[i][1]==-1) ch[i][1]=0;
         }
        Dfs(1);
        printf("%u
    ",ans); 
        return 0;
    }
  • 相关阅读:
    python基础_字典_列表_元组考试_day4
    基本数据类型-列表_元组_字典_day4
    python基础-基本数据类型总结_整型(int)_字符型(str)_day3
    python基础-range用法_python2.x和3.x的区别
    python基础--基本数据类型考试_day3
    批量创建文件和修改文件
    批量建立用户及密码
    打印九九乘法表
    Error Code : 1456 Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine pro_app_rs_right_update···
    mysql 创建视图出现1349 View's SELECT contains a subquery in the FROM clause解决办法
  • 原文地址:https://www.cnblogs.com/rrsb/p/9318168.html
Copyright © 2011-2022 走看看