[atARC087F]Squirrel Migration
对这棵树重心情况分类讨论:
1.若这棵树存在两个重心,分别记作$x$和$y$,如果将$(x,y)$断开,两棵子树大小都相同(都为$\frac{n}{2}$),此时$p_{i}$与$i$必然不同属于一个连通块中,证明如下:
考虑若$p_{i}$与$i$在一个连通块中,则必然有$p_{j}$和$j$也在同一个连通块中且与$i$不同,将其交换一定更优
将距离拆为两颗子树内部+$(x,y)$,即有$mx=2\sum dep_{i}(以(x,y)为根)+n$,方案数为$(\frac{n}{2}!)^{2}$
2.若这棵树仅有1个重心,类似于Distance Matching,若以重心为根,$mx=2\sum dep_{i}$
问题相当于要求任意$i$和$p_{i}$不在重心的同一个儿子中,考虑容斥,令集合$S$表示$i$和$p_{i}$在重心的同一个儿子中的$i$,$f_{S}$表示对应方案数
对$S$和$S$以外的的点分别计算(再相乘):
1.对$S$以外,考虑$i\in S$,其实可以将$p_{i}$理解为$i$,换言之将$p_{j}=i$的位置改为$p_{j}=p_{i}$即可,因此剩下的点任意排列,方案数为$(n-|S|)!$
2.对$S$以内,即从子树中选$i$个,即为$\prod_{son}a_{son}!c(sz_{son},a_{son})$($son$表示重心的儿子,$a_{son}$表示son子树内所选的节点个数)
由于$|S|=\sum_{son}a_{son}$,因此答案仅与$a_{i}$有关,对应答案为$(n-\sum_{son}a_{son})!\prod_{son}a_{son}!c(sz_{son},a_{son})^{2}$(对应的$|S|$有$\prod_{son}c(sz_{son},a_{son})$种)
令$f_{i}$表示当$\sum_{son}a_{son}=i$时$\prod_{son}c(sz_{son},a_{son})^{2}$的和,dp转移即可,时间复杂度为$o(n^{2})$(枚举子树和$a_{i}$的总量为$o(n)$),还可以用分治fft优化到$o(n\log^{2}n)$

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 5005
4 #define mod 1000000007
5 struct ji{
6 int nex,to;
7 }edge[N<<1];
8 vector<int>v;
9 int E,n,m,x,y,ans,head[N],sz[N],fac[N],inv[N],f[N][N];
10 int sqr(int n){
11 return 1LL*n*n%mod;
12 }
13 int c(int n,int m){
14 return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
15 }
16 void add(int x,int y){
17 edge[E].nex=head[x];
18 edge[E].to=y;
19 head[x]=E++;
20 }
21 void dfs(int k,int fa){
22 int mx=0;
23 sz[k]=1;
24 for(int i=head[k];i!=-1;i=edge[i].nex)
25 if (edge[i].to!=fa){
26 dfs(edge[i].to,k);
27 mx=max(mx,sz[edge[i].to]);
28 sz[k]+=sz[edge[i].to];
29 }
30 if (max(mx,n-sz[k])<=n/2){
31 if (!x)x=k;
32 else y=k;
33 }
34 }
35 int main(){
36 fac[0]=inv[0]=inv[1]=1;
37 for(int i=1;i<N-4;i++)fac[i]=1LL*fac[i-1]*i%mod;
38 for(int i=2;i<N-4;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
39 for(int i=1;i<N-4;i++)inv[i]=1LL*inv[i]*inv[i-1]%mod;
40 scanf("%d",&n);
41 memset(head,-1,sizeof(head));
42 for(int i=1;i<n;i++){
43 scanf("%d%d",&x,&y);
44 add(x,y);
45 add(y,x);
46 }
47 x=y=0;
48 dfs(1,0);
49 if (y){
50 printf("%d",sqr(fac[n/2]));
51 return 0;
52 }
53 dfs(x,0);
54 v.push_back(0);
55 for(int i=head[x];i!=-1;i=edge[i].nex)v.push_back(sz[edge[i].to]);
56 m=v.size()-1;
57 f[0][0]=1;
58 int s=0;
59 for(int i=1;i<=m;i++){
60 for(int j=0;j<=s;j++)
61 for(int k=0;k<=v[i];k++)
62 f[i][j+k]=(f[i][j+k]+1LL*fac[k]*sqr(c(v[i],k))%mod*f[i-1][j])%mod;
63 s+=v[i];
64 }
65 assert(s==n-1);
66 for(int i=0;i<n;i++){
67 int s=1LL*f[m][i]*fac[n-i]%mod;
68 if (i&1)s=mod-s;
69 ans=(ans+s)%mod;
70 }
71 printf("%d",ans);
72 }
[atARC087F]Squirrel Migration的更多相关文章
- AT3728 Squirrel Migration
AT3728 Squirrel Migration 就是给每个点分配两个匹配点(自环除外) 考虑最大值 考虑极限情况:每个边的贡献是min(sz[u],sz[v])*2 证明存在方案: 发现,如果哪边 ...
- [ARC087D] Squirrel Migration 补题记录
题目链接 简要题意: 给你一个\(N\)个节点的树,求一个\(1\cdots N\)的排列\((p_1,p_2,\cdots p_N)\) ,使得\(\sum dist(i,p_i)\)最大. 求这样 ...
- Atcoder 乱做
最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...
- 【AtCoder】ARC087
C - Good Sequence 题解 用个map愉悦一下就好了 代码 #include <bits/stdc++.h> #define fi first #define se seco ...
- 写给.NET开发者的数据库Migration方案
微软给我们提供了一种非常好用的数据库迁移方案,但是我发现周围的同学用的并不多,所以我还是想把这个方案整理一下..NET选手看过来,特别是还在通过手工执行脚本来迁移数据库的同学们,当然你也可以选择EF的 ...
- EF Core 数据库迁移(Migration)
工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用 Pomelo.EntityFrameworkCore.MySql 源代码地址(https://github. ...
- Database first with EntityFramework (Migration)安装和升级
最近看了国外几个项目,发现用EntityFramework做Code First的项目现在很流行. 最让我有兴趣的一个功能则是,EntityFramework对于数据库的安装和升级的无缝完美支持,且很 ...
- Squirrel: 通用SQL、NoSQL客户端
安装 配置数据库 配置驱动 配置连接 如果你的工作中,需要使用到多个数据库,又不想在多种客户端之间切换来切换去.那么就需要找一款支持多数据库的客户端工具了.如果你要连接多个关系型数据库,你就可以使用N ...
- Laravel使用笔记 —— migration
在使用 php artisan make:migration 创建migration时,可用 --path 指定创建migration文件的路径, 如果在执行的 php artisan migrate ...
随机推荐
- DL4J实战之二:鸢尾花分类
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- docker-compose 搭建mongo集群
创建目录 在每台机器上操作此步骤 一.在编写容器文件之前的注意事项: 1.yaml文件的指令前端不能使用tab键只能使用空格 2.storage: 指令的对接只能使用 : 不能使用 = 冒号的后面要跟 ...
- 讲讲java中线程池的实现
今天跟一个同学谈到java中的线程池的实现,才发现有些知识点已经记不清了,所以特意把源码打开,对官方文档做了些说明. 其实这些理解了之后,读懂源码应该是没多大问题了,有感兴趣的小伙伴们可以看完说明后自 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- Java:内部类小记
Java:内部类小记 对 Java 中的 内部类,做一个微不足道的小小小小记 首先:内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的. 成员内部类 成员内 ...
- 【二食堂】Alpha- 发布声明
MarkTexting Alpha版本发布声明 今日我们的MarkTexting正式上线了! 功能介绍 我们实现了一个简单的文本标注生成知识图谱的网站,在Alpha阶段,我们实现的功能有: 登陆注册 ...
- 2021.8.3考试总结[NOIP模拟29]
T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...
- 简说各种wifi无线协议的传输速率
简说各种wifi无线协议的传输速率 acwifi.net 发布于 2016-10-26 分类:路由器评测 阅读(59953) 评论(1) 802.11ad 60G无线传输,这是未来的方向,先不谈这个. ...
- 『学了就忘』Linux基础 — 15、了解Linux系统的目录结构
目录 1.一级目录说明 (1)一级目录列表 (2)/bin/和/sbin/目录说明 (3)/boot/目录说明 (4)/lib/和/lib64/目录说明 (5)/lost+found/目录说明 (6) ...
- Spring事务不生效问题
事务未生效可能造成严重的数据不一致性问题,因而保证事务生效至关重要.Spring事务是通过Spring aop实现的,所以不生效的本质问题是spring aop没生效,或者说没有代理成功,所以有必要了 ...