传送门

正儿八经的树哈希的模板题。

哈希方法是求出每个儿子的哈希值,排序,末尾加上该点的size连成一个串,再对这个串哈希。

因为要求出A所有同构的树的hash值,直接hash的复杂度是n^n log

先随便指定一个根哈希一遍,再树dp换根即可,换根的时候把每个人父亲传过来的hash值也扔进串中,然后对每个人的串求前后缀,就可以方便地计算出它的hash值和它要传给每个儿子的hash值了。

然后对于B树要求去掉一个叶子的hash值,那么一个点传给它的叶子儿子的值就是一个合法的值,此外单独考虑一下根的父亲是叶子的情况即可。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<map>
const int N=1e5+7,mod=998244353,bs=1011139;
typedef long long LL;
using namespace std;
int n,tot,ans=-1;
map<LL,int>mp;
LL power[N],fh[N];template<typename T> void read(T &x) {char ch=getchar(); x=0; T f=1;while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') f=-1,ch=getchar();for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}int ecnt,fir[N],nxt[N*2],to[N*2],sz[N],ha[N],f[N];
void add(int u,int v) {nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}bool cmp(const int &A,const int &B) { return ha[A]<ha[B]; }vector<int>v[N];
void get_hash(int x) {int up=v[x].size();ha[x]=0;sort(v[x].begin(),v[x].end(),cmp);for(int i=0;i<up;i++) ha[x]=((LL)ha[x]+(LL)ha[v[x][i]]*power[i+1]%mod)%mod;ha[x]=((LL)ha[x]+sz[x])%mod;
}void dfs(int x,int fa) {sz[x]=1; f[x]=fa;for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {dfs(to[i],x);v[x].push_back(to[i]);sz[x]+=sz[to[i]];}get_hash(x);
}int pr[N];
void make_hash(int x) {sort(v[x].begin(),v[x].end(),cmp);int up=v[x].size(); pr[0]=0;for(int i=0;i<up;i++) pr[i+1]=((LL)pr[i]+power[i+1]*ha[v[x][i]])%mod;LL has=0;ha[x]=(pr[up]+tot)%mod;for(int i=up-1;i>=0;i--) {if(v[x][i]!=n+2) {fh[v[x][i]]=((has*power[i]%mod+pr[i])%mod+(tot-sz[v[x][i]]))%mod;if(ecnt==2*n&&!nxt[fir[v[x][i]]]&&mp[fh[v[x][i]]]) if(ans==-1||v[x][i]<ans) ans=v[x][i];} else if(ecnt==2*n&&!nxt[fir[f[x]]]) {LL tpp=((has*power[i]%mod+pr[i])%mod+(tot-1))%mod;if(mp[tpp]) if(ans==-1|f[x]<ans) ans=f[x];}has=(has+ha[v[x][i]])*bs%mod;}
}void dp(int x,int fa) {if(fa) { ha[n+2]=fh[x]; v[x].push_back(n+2); }make_hash(x);for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {dp(to[i],x);}
}int main() {read(n); power[0]=1; tot=n;for(int i=1;i<=n;i++) power[i]=power[i-1]*bs%mod;for(int i=1;i<n;i++) {int u,v; read(u); read(v); add(u,v); }dfs(1,0); dp(1,0);for(int i=1;i<=n;i++) mp[ha[i]]=1,v[i].clear();memset(fir,0,sizeof(fir)); ecnt=0; tot++;for(int i=1;i<=n;i++) {int u,v; read(u); read(v); add(u,v); }dfs(1,0); dp(1,0);printf("%d\n",ans);return 0;
}
/*
5
1 2
2 3
1 4
1 5
1 2
2 3
3 4
4 5
3 6
*/ 

View Code

转载于:https://www.cnblogs.com/Achenchen/p/8390780.html

bzoj4754: [Jsoi2016]独特的树叶相关推荐

  1. BZOJ4754 JSOI2016独特的树叶(哈希)

    判断两棵无根树是否同构只需要把重心提作根哈希即可.由于只添加了一个叶子,重心的位置几乎不发生偏移,所以直接把两棵树的重心提起来,逐层找哈希值不同且对应的两子树即可.被一个普及组子问题卡一年. #inc ...

  2. P5043 【模板】树同构([BJOI2015]树的同构 // P4323 [JSOI2016]独特的树叶

    一.P5043 [模板]树同构([BJOI2015]树的同构): #include<iostream> #include<cstdio> #include<algorit ...

  3. 洛谷 - P4323 [JSOI2016]独特的树叶(树上哈希+换根dp)

    题目链接:点击查看 题目大意:给出一棵 n 个节点的树 A ,再给出一棵 n + 1 个节点的树 B,题目保证了树 B 是树 A 添加了一个叶子结点后的一棵树,只不过编号的顺序不同,现在问这个叶子节点 ...

  4. P4323-[JSOI2016]独特的树叶【换根dp,树哈希】

    正题 题目链接:https://www.luogu.com.cn/problem/P4323 题目大意 给出nnn个点的树和加上一个点之后的树(编号打乱). 求多出来的是哪个点(如果有多少个就输出编号 ...

  5. 【BZOJ - 4754】独特的树叶(树哈希)

    题干: JYY有两棵树A和B:树A有N个点,编号为1到N:树B有N+1个点,编号为1到N+1.JYY知道树B恰好是由树A加上一个叶 节点,然后将节点的编号打乱后得到的.他想知道,这个多余的叶子到底是树 ...

  6. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  7. 哈希算法在判定树同构方面的应用(下)

    哈希算法在判定树同构方面的应用 在上一篇文章中我们介绍了 枚举根节点哈希 和 求重心哈希 两种方法来判断两棵无根树是否同构. 但是如果有些题目中我必须要计算出每个根节点的 fff 值,且 n≤1e5n ...

  8. 怎样设计一个好玩的游戏——游戏设计的艺术

    前言: 一个好玩的游戏,就是要让玩家在玩游戏的过程中感到愉快的游戏体验.游戏品质一般可以分为三个层次:普通.精品.经典. 仅仅要游戏能赚钱的好游戏可算是精品游戏,而经典的游戏,必定有深厚的游戏内涵,甚 ...

  9. 树叶贴画机器人_洪山广场举办“落叶节”,树叶树枝拼贴出冬日风景

    楚天都市报11月30日讯(记者卢成汉 通讯员谢助全 彭雪琴)秋天飘落的树叶树枝,经过拼贴,变成了有趣的图案.29日,洪山广场举行的"落叶节"上,小学生们的树叶作品,拼贴成冬日的风景 ...

  10. 树叶贴画机器人_学生手工论文,关于对学前教育手工课教学相关参考文献资料-免费论文范文...

    导读:这篇学生手工论文范文为免费优秀学术论文范文,可用于相关写作参考. (平凉工业中等专业学校) 摘 要:手工制作是一项既能锻炼人的思维又能开发智力的活动,中职学校学前教育专业的手工教学是一门专业性很 ...

最新文章

  1. xz命令--Linux命令应用大词典729个命令解读
  2. 性能测试(01)-jmeter元件-线程组、调试取样器
  3. 软件工程模块开发卷宗_软件智能化再进一步,未来人人都能开发软件?
  4. JavaWeb课程复习资料(十)——修改功能
  5. vi常用命令与设置(不断修改中)
  6. java ioutils 写入文件_文件输入输出流工具: IOUtils使用总结
  7. 苹果笔记本电脑亮度无法调节_苹果更新笔记本加量还降价,教育优惠全面开启!...
  8. [原创]Scala学习:编写Scala脚本
  9. 新iPhone模具曝光:刘海屏无变化 后置三摄排布辣眼
  10. 第十一章:WebSocket
  11. Android 颜色渲染(六) RadialGradient 环形渲染
  12. cogs 315. [POJ3255] 地砖RoadBlocks
  13. ElasticSearch学习笔记(二)
  14. 电子电工产品IP防水测试及测试设备
  15. 为什么称冯诺依曼为电子计算机之父,为什么说冯诺依曼是现代电子计算机之父...
  16. Vue官网下载Vue.js和Vue.min.js
  17. 数字逻辑电路仿真电路:与非门组成的三人表决器
  18. ArcGIS API for JavaScript 4.X Basemap类(史上最全)
  19. spring——Spring自动装配——示例
  20. r5 5600u和i5 10300h 选哪个

热门文章

  1. (16)数据结构-并查集
  2. 数据结构第三章栈和队列(一)
  3. c语言程序设计基础考点,c语言程序设计知识点
  4. 全卷机神经网络图像分割(U-net)-keras实现
  5. 数据挖掘数据的资料分享
  6. Hadoop 2.6.0 HA高可用集群配置详解
  7. 零基础学启发式算法(6)-蚁群算法 (Ant Colony Optimization, ACO)
  8. C++ const和static const的区别
  9. 【Django 2021年最新版教程15】数据库定义 models字段类型 限制 用法 总结
  10. java数组写入excel_java - 如何使用Java将数组数据写入Excel - 堆栈内存溢出