[树的同构][二分][可并堆维护哈希] LOJ#6066 || BZOJ4928 && 2017 山东一轮集训 Day3. 第二题

这题一看就可以二分
那么解决这题的关键就变成了怎么对树进行哈希,以及怎么快速维护哈希值
想了一个下午想了一个比较靠谱的哈希方法。
用一个p进制数(p>n且为质数)来表示每一个节点,这个数有depth位,depth位这个节点的深度,那么这个数在p进制下第i位表示这个点的depth-i的祖先是其父亲的第几个儿子。
这里写图片描述

大概长这样
子树中所有节点的哈希值之和作为这个子树的哈希值。
因为每个哈希值的组合表示了唯一一颗子树,那么出现哈希值重合但是不同构的子树的概率就很小了

在二分中检验的时候,dfs一遍,可以用按深度建可并堆来维护K-子树,每次合并子树的可并堆,并在子树可并堆上打个乘p+tag的标记,并且把深度超过二分的d时弹出堆,然后用map记一下哈希值就可以了。

轻松垫底

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cstring>

using namespace std;

const int N=100010,base=100003;

typedef unsigned long long ll;

int n,x,u,cnt;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值