Educational Codeforces Round 17F Tree nesting
来自FallDream的博客,未经允许,请勿转载, 谢谢。
给你两棵树,一棵比较大(n<=1000),一棵比较小(m<=12) 问第一棵树中有多少个连通子树和第二棵同构。
答案取膜1e9+7
考虑在大树中随便选个根,然后在小的那棵那里枚举一个根作为大树中深度最小的节点(注意哈希判同构)
然后f[x][y]表示大树的x节点作为小树的y节点的方案数。
如果y是叶子结点,f[x][y]=1
否则要用x的儿子中的一些节点表示y的所有叶子节点。
考虑一个状压dp,g[i][s]表示前i个儿子表示了小树的s集合内的节点的方案数,容易转移。
然后如果y有一些儿子同构,则需要除以个数的阶乘。
复杂度上界是n*m*2^m
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
#define MN 1000
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
unsigned long long ha[MN+];vector<unsigned long long> v[MN+];map<unsigned long long,int> mp,mp2;
int n,m,head[MN+],Head[MN+],fa[MN+],cnt=,f[MN+][],F[<<],size[MN+],son[MN+],q[MN+],ans=,now,P[];
struct edge{int to,next;}e[MN*+];
inline void R(int&x,int y){x+=y;x>=mod?x-=mod:;}
inline void ins(int*H,int f,int t)
{
e[++cnt]=(edge){t,H[f]};H[f]=cnt;
e[++cnt]=(edge){f,H[t]};H[t]=cnt;
} int pow(int x,int k)
{
int sum=;
for(;k;k>>=,x=1LL*x*x%mod)
if(k&) sum=1LL*sum*x%mod;
return sum;
} void GetHa(int x,int f)
{
ha[x]=;size[x]=;v[x].clear();fa[x]=f;
for(int i=Head[x];i;i=e[i].next)
if(e[i].to!=f)
{
GetHa(e[i].to,x);
v[x].push_back(ha[e[i].to]);
}
son[x]=v[x].size();
sort(v[x].begin(),v[x].end());
for(int i=;i<v[x].size();++i) ha[x]=ha[x]*+v[x][i];
ha[x]=ha[x]*+size[x];
} void Solve(int x,int fat)
{
int num=;
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fat) Solve(e[i].to,x),++num;
for(int i=;i<=m;++i)
{
if(!son[i]){f[x][i]=;continue;}
if(num<son[i]){f[x][i]=;continue;}
for(int k=;k<<<son[i];++k)F[k]=;
F[]=;int top=;
for(int j=Head[i];j;j=e[j].next) if(e[j].to!=fa[i]) q[++top]=e[j].to,++mp2[ha[e[j].to]];
for(int j=head[x];j;j=e[j].next)
if(e[j].to!=fat)
{
for(int s=(<<top)-;~s;--s)
for(int k=;k<=top;++k) if(f[e[j].to][q[k]])
if(!(s&(<<k-))) R(F[s|(<<k-)],1LL*F[s]*f[e[j].to][q[k]]%mod);
}
f[x][i]=F[(<<top)-];
for(int j=;j<=top;++j)
if(mp2[ha[q[j]]]) f[x][i]=1LL*f[x][i]*pow(P[mp2[ha[q[j]]]],mod-)%mod,mp2[ha[q[j]]]=;
}
R(ans,f[x][now]);
} int main()
{
n=read();P[]=;
for(int i=;i<=;++i) P[i]=1LL*P[i-]*i%mod;
for(int i=;i<n;++i) ins(head,read(),read());m=read();
for(int i=;i<m;++i) ins(Head,read(),read());
for(int i=;i<=m;++i)
{
GetHa(i,);
if(mp[ha[i]]) continue;
memset(f,,sizeof(f));mp[ha[i]]=;
now=i;Solve(,);
}
printf("%d\n",ans);
return ;
}
Educational Codeforces Round 17F Tree nesting的更多相关文章
- Educational Codeforces Round 17
Educational Codeforces Round 17 A. k-th divisor 水题,把所有因子找出来排序然后找第\(k\)大 view code //#pragma GCC opti ...
- Educational Codeforces Round 35 (Rated for Div. 2)
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
- Educational Codeforces Round 67
Educational Codeforces Round 67 CF1187B Letters Shop 二分 https://codeforces.com/contest/1187/submissi ...
- Educational Codeforces Round 41 967 E. Tufurama (CDQ分治 求 二维点数)
Educational Codeforces Round 41 (Rated for Div. 2) E. Tufurama (CDQ分治 求 二维点数) time limit per test 2 ...
- [Educational Codeforces Round 16]E. Generate a String
[Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...
- [Educational Codeforces Round 16]D. Two Arithmetic Progressions
[Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...
- [Educational Codeforces Round 16]C. Magic Odd Square
[Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...
- [Educational Codeforces Round 16]B. Optimal Point on a Line
[Educational Codeforces Round 16]B. Optimal Point on a Line 试题描述 You are given n points on a line wi ...
- [Educational Codeforces Round 16]A. King Moves
[Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...
随机推荐
- Basys3在线调试视频指南及代码
fpga在线调试视频链接 FPGA选择型号:xc7a35tcpg236-1 des文件 `timescale 1ns / 1ps module top( output [1:0] led, outpu ...
- 【iOS】swift-如何理解 if let 与guard?
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:黄兢成 链接:http://www.zhihu.com/question/36448325/answer/68614858 ...
- C#中委托。
委托(delegate):是一个类型.其实winform中控件的事件也是特殊的委托类型. 如: 自定义委托:自定义委托在winform中的用法. 当要在子线程中更新UI时,必须通过委托来实现. pri ...
- 逆向集录_00_不同程序OEP特征总结
在分析/逆向 程序时,如果事先知道这类程序的一些特征,那将会是事半功倍的: 分析/逆向 程序,和写程序不同,比喻的话:写程序像在作案,分析/逆向 程序就像是在破案,对破案来讲,重在假想和推理: 特征1 ...
- 怎么用DreamWare新建立一个静态网站的站点
可以上面的图可以看出首先需要用F8确定这个文件是勾选的,然后在D盘建立"华为"文件夹,然后在里面建js,css,image文件夹,然后在DW里面点击站点 然后点击管理站点,有一个新 ...
- Mego(1) - NET中主流ORM框架性能对比
从刚刚开始接触ORM到现在已有超过八年时间,用过了不少ORM框架也了解了不少ORM框架,看过N种关于ORM框架的相关资料与评论,各种言论让人很难选择.在ORM的众多问题中最突出的问题是关于性能方面的问 ...
- PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式
php模式设计之单例模式 什么是单例模式? 单例模式是指在整个应用中只有一个实例对象的设计模式 为什么要用单例模式? php经常要链接数据库,如果在一个项目中频繁建立连接数据库,会造成服务器资源的很大 ...
- HTTP协议扫盲(七)请求报文之 GET、POST-FORM 和 POST-FILE
一.get 1.页面代码 2.请求报文 3.小结 get请求没有报文体,所以请求报文没有content-type url上的query参数param11=val11¶m12=val12 ...
- redux的使用过程
1.redux是react的状态管理工具,可以用来存放公共数据,因此也可用来作为组件间参数传递的方法. 2.组件传参,需要有一个公共的父组件.在父组件中引入Provider.通过Provider将 ...
- 二、配置QtDesigner、PyUIC及PyRcc
配置QtDesigner.PyUIC及PyRcc 安装完PyQt 5 及PyQt5-tools 后,则需要在Pycharm中配置QtDesigner.PyUIC及PyRcc. 配置QtDesigner ...