题面

BZOJ

题解

忽然翻到这道题目,突然发现就是前几天一道考试题目。。。
题解:
树哈希,既然只考虑这一棵树,那么,如果两个点为根是同构的,
他们的重心相同,所以直接找出树的重心,以重心为根进行转移
提前预处理每一棵子树的哈希值,因为相同的子树是同构的,所以转移相当于是可重组合的计算。
对于存在两个重心的情况,分两个重心的子树同构还是不同构。
如果不同构则随便选择一个重心即可。如果同构,则建立一个虚点,然后dpdpdp
最后容斥一下即可。
中间算组合数的时候,发现只与儿子个数有关,所以可以爆算。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ull unsigned long long
#define ll long long
#define RG register
#define MAX 500500
#define MOD 1000000007
#define inv2 500000004
inline int read()
{RG int x=0,t=1;RG char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=-1,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*t;
}
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=2;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int f[MAX][2],ans,n,size[MAX],rt,rt2,S[MAX],top,msz[MAX];
const ull base1=19;
const ull base2=19260817;
const ull base3=1e16+5;
ull Hash[MAX];
int jc[MAX],jv[MAX],inv[MAX];
bool cmp(int a,int b){return Hash[a]<Hash[b];}
int C(int n,int m)
{if(m<n-m)m=n-m;int ret=1;for(int i=n;i>m;--i)ret=1ll*ret*i%MOD;ret=1ll*ret*jv[n-m]%MOD;return ret;
}
void getroot(int u,int ff)
{size[u]=1;for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(v==ff)continue;getroot(v,u);size[u]+=size[v];msz[u]=max(msz[u],size[v]);}msz[u]=max(msz[u],n-size[u]);if(msz[u]<msz[rt])rt=u;else if(msz[u]==msz[rt])rt2=u;
}
void DFS(int u,int ff)
{for(int i=h[u];i;i=e[i].next)if(e[i].v!=ff)DFS(e[i].v,u);f[u][0]=f[u][1]=1;top=0;for(int i=h[u];i;i=e[i].next)if(e[i].v!=ff)S[++top]=e[i].v;sort(&S[1],&S[top+1],cmp);for(int i=1,j;i<=top;i=j+1){j=i;while(j!=top&&Hash[S[j+1]]==Hash[S[i]])++j;int t=j-i+1,s0=(f[S[i]][0]+f[S[i]][1])%MOD,s1=f[S[i]][0];s0=C(s0+t-1,t);s1=C(s1+t-1,t);f[u][0]=1ll*f[u][0]*s0%MOD;f[u][1]=1ll*f[u][1]*s1%MOD;}
}
void GetHash(int u,int ff)
{Hash[u]=0;size[u]=1;int son=0;for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(v==ff)continue;GetHash(v,u);size[u]+=size[v];Hash[u]^=Hash[v]+base1;++son;}Hash[u]+=base2*size[u]+base3*son*son*size[u];
}
int main()
{n=read();jc[0]=jv[0]=inv[0]=inv[1]=1;msz[0]=1e9;for(int i=1;i<n;++i){int u=read(),v=read();Add(u,v);Add(v,u);}for(int i=2;i<=n;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;for(int i=1;i<=n;++i)jc[i]=1ll*jc[i-1]*i%MOD;for(int i=1;i<=n;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;getroot(1,0);if(msz[rt]==msz[rt2]){GetHash(rt,rt2);GetHash(rt2,rt);if(Hash[rt]!=Hash[rt2]){DFS(rt,rt2);DFS(rt2,rt);add(ans,1ll*f[rt][0]*f[rt2][0]%MOD);add(ans,1ll*f[rt][1]*f[rt2][0]%MOD);add(ans,1ll*f[rt][0]*f[rt2][1]%MOD);}else{Add(n+1,rt);Add(n+1,rt2);for(int i=h[rt2];i;i=e[i].next)if(e[i].v==rt){e[i].v=e[i^1].v=n+1;break;}DFS(n+1,0);ans=C(f[rt][1]+1,2);ans=MOD-ans;add(ans,f[n+1][0]);}}else GetHash(rt,0),DFS(rt,0),ans=(f[rt][0]+f[rt][1])%MOD;printf("%d\n",ans);return 0;
}

【BZOJ3162】独钓寒江雪(树哈希,动态规划)相关推荐

  1. bzoj 3162: 独钓寒江雪 树哈希+树形dp

    题意 给出一棵无标号无根树,问本质不同的最大独立集数量.答案模1e9+7. n<=500000 分析 对于一般的情况,我们可以先找出树的重心作为根,然后进行树形dp.这样做有什么好处呢?通过根的 ...

  2. 洛谷4895 BZOJ3162 独钓寒江雪 树形dp 树哈希

    题目链接 题意: 给定一棵无根树,求其中本质不同的独立集的个数.独立集就是一个集合中的点之间都没有边直接相连.n<=5e5n<=5e5n<=5e5,对1e9+71e9+71e9+7取 ...

  3. 洛谷4895 独钓寒江雪 (树哈希+dp+组合)

    qwq 首先,如果是没有要求本质不同的话,那么还是比较简单的一个树形dp 我们令dp[i][0/1]dp[i][0/1]dp[i][0/1]表示是否iii的子树,是否选iii这个点的方案数. 一个比较 ...

  4. LeetCode第 57 场力扣夜喵双周赛(差分数组、单调栈) and 第 251 场力扣周赛(状态压缩动规,树的序列化,树哈希,字典树)

    LeetCode第 57 场力扣夜喵双周赛 离knight勋章越来越近,不过水平没有丝毫涨进 1941. 检查是否所有字符出现次数相同 题目描述 给你一个字符串 s ,如果 s 是一个 好 字符串,请 ...

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

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

  6. 树的同构模板题(法1.最小表示法+法2.树哈希)

    树的同构 problem solution code solution code problem 模板题 solution Ⅰ. 最小表示法 将树转化为 0/10/10/1 括号序列:从根开始 dfs ...

  7. BZOJ.4337.[BJOI2015]树的同构(树哈希)

    BZOJ 洛谷 \(Description\) 给定\(n\)棵无根树.对每棵树,输出与它同构的树的最小编号. \(n及每棵树的点数\leq 50\). \(Solution\) 对于一棵无根树,它的 ...

  8. 洛谷 - P5043 【模板】树同构([BJOI2015]树的同构)(树上哈希)

    题目链接:点击查看 题目大意:给出 m 棵树,对于第 i 棵树而言,找到 1 ~ i 中与当前树同构的最小 id 题目分析:判断有向树同构,可以预处理出质数数组 p ,然后树形 dp ,设 u 为当前 ...

  9. 2020CCPC(威海) - Caesar Cipher(线段树+哈希)

    题目大意:给出一个长度为 n 的序列,接下来有 m 次操作,每次操作分为下列两种类型: 1 l r:区间 [ l , r ] 内的所有数都加 1 并对 65536 取模,也就是 i ∈ [ l , r ...

  10. 储存引擎InnoDB 索引选择 为何是B+树 而不是 B树 哈希表

    一:概述 首先需要澄清的一点是,MySQL 跟 B+ 树没有直接的关系,真正与 B+ 树有关系的是 MySQL 的默认存储引擎 InnoDB,MySQL 中存储引擎的主要作用是负责数据的存储和提取,除 ...

最新文章

  1. Building a Simple, Local, Python Blockchain – Part 1
  2. java编写一个函数_请教如何用java编写一个函数图像生成的应用程序?谢谢!
  3. 图论--拓扑排序--模板
  4. bzoj2375 疯狂的涂色
  5. Spring Bean初始化过程
  6. php数组 函数,PHP array_uintersect_uassoc() 函数
  7. 写文件 追加到开始_文件和流
  8. Docker学习文档之三 其他相关-安全性
  9. 设计灵感|排版太死板?提高品质的角度很重要
  10. 最快学习之Vue Route
  11. WEB打印分页类(JS)
  12. firebug 调试
  13. html桌面程序实例spark,【01】Spark 简单实例
  14. Java开发实战经典学习记录(一)
  15. 什么是IEC球压测试?
  16. 主编编辑器如何绑定公众号?
  17. 【Unity】 2D贪吃豆开发流程
  18. 有道无术,术尚可求;有术无道,止于术!
  19. mscorsvw.exe进程占用CPU资料80%以上的原因
  20. 第三方登录/分享最佳实践

热门文章

  1. 美团 2021 届秋季校园招聘—小团的 AB 队(排序)
  2. codeforces 129C - Statues 图论 DFS
  3. 【Leetcode刷题Python】739. 每日温度
  4. 电影TS/TC/SCR/R5/BD/HD/HC版本意思收集(转)
  5. 【peoplesoft】Integration Gateway - General Error (158,10201)错误
  6. 事务故障、介质故障、系统故障恢复方法及区别
  7. 抖音,新的流量洼地?
  8. [spring源码学习]一、IOC简介
  9. Windows 找不到休眠怎么办?
  10. 数据库分析之概念结构设计