AT3728 Squirrel Migration

就是给每个点分配两个匹配点(自环除外)

考虑最大值

考虑极限情况:每个边的贡献是min(sz[u],sz[v])*2

证明存在方案:

发现,如果哪边sz更小,就把这些边都往外连

这样,在重心的位置,会两两匹配闭合。

所以存在构造方案。

方案数?就是最后匹配的方案

重心两个:((n/2)!)^2

重心一个:

也就是,以重心为根,每个子树是一个组,每个组必须匹配别的组

而重心自己可以连自环或者匹配任意一个组

枚举重心连自环与否,做两遍。

现在有若干个组,每个组有num[i]个元素,每个组不能匹配自己的元素

考虑容斥!

f[i][j]前i个组,有j个位置连了自己组的元素的方案数

f[i][j+k]+=f[i-1][j]*C(num[i],k)*A(num[i],k)

看似O(n^3),实际和树形背包的sz优化一样,就是O(n^2)的

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=1e9+;
int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;}
void inc(int &x,int y){x=ad(x,y);}
int mul(int x,int y){return (ll)x*y%mod;}
void inc2(int &x,int y){x=mul(x,y);}
int qm(int x,int y=mod-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}return ret;}
}
using namespace Modulo;
namespace Miracle{
const int N=;
int n;
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
int jie[N],inv[N];
int C(int n,int m){
if(n<||m<||n<m) return ;
return mul(jie[n],mul(inv[m],inv[n-m]));
}
int A(int n,int m){
return mul(C(n,m),jie[m]);
}
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
int be[N],sz[N],num[N],tot;
int rt[N];
void dfs(int x,int fa){
sz[x]=;
int mx=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
dfs(y,x);
sz[x]+=sz[y];
if(sz[y]>mx) mx=sz[y];
}
mx=max(mx,n-sz[x]);
if(mx<=n/){
rt[++rt[]]=x;
}
}
void fin(int x,int fa){
be[x]=tot;
++num[be[x]];
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
if(x==rt[]){
++tot;
}
fin(y,x);
}
}
int f[N][N];
int calc(){
memset(f,,sizeof f);
f[][]=;
int sum=;
for(reg i=;i<=tot;++i){
// cout<<" i "<<i<<" "<<num[i]<<endl;
for(reg j=;j<=sum;++j){
for(reg k=;k<=num[i];++k){
// cout<<" con "<<mul(f[i-1][j],mul(C(num[i],k),A(num[i],k)))<<endl;
f[i][j+k]=ad(f[i][j+k],mul(f[i-][j],mul(C(num[i],k),A(num[i],k))));
}
}
sum+=num[i];
}
ll ret=;
for(reg j=;j<=sum;++j){
// cout<<f[tot][j]<<endl;
if(j&){
ret=ad(ret,mod-mul(f[tot][j],jie[sum-j]));
}else{
ret=ad(ret,mul(f[tot][j],jie[sum-j]));
}
}
return ret;
}
int main(){
rd(n);
jie[]=;
for(reg i=;i<=n;++i) jie[i]=mul(jie[i-],i);
inv[n]=qm(jie[n]);
for(reg i=n-;i>=;--i) inv[i]=mul(inv[i+],i+);
int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
add(x,y);add(y,x);
}
dfs(,);
if(rt[]==){
ll ans=qm(jie[n/],);
ot(ans);return ;
}
// cout<<rt[1]<<endl;
fin(rt[],);
// cout<<" tot "<<tot<<endl;
// prt(be,1,n);
int ans=calc();
// cout<<" ans1 "<<ans<<endl;
num[++tot]=;
ans=ad(ans,calc());
ot(ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/

构造最大值,考虑上界,再证明能不能达到。

然后构造方案很明确了,方案数就是分组,容斥DP来处理

AT3728 Squirrel Migration的更多相关文章

  1. [ARC087D] Squirrel Migration 补题记录

    题目链接 简要题意: 给你一个\(N\)个节点的树,求一个\(1\cdots N\)的排列\((p_1,p_2,\cdots p_N)\) ,使得\(\sum dist(i,p_i)\)最大. 求这样 ...

  2. [atARC087F]Squirrel Migration

    对这棵树重心情况分类讨论: 1.若这棵树存在两个重心,分别记作$x$和$y$,如果将$(x,y)$断开,两棵子树大小都相同(都为$\frac{n}{2}$),此时$p_{i}$与$i$必然不同属于一个 ...

  3. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

  4. 【AtCoder】ARC087

    C - Good Sequence 题解 用个map愉悦一下就好了 代码 #include <bits/stdc++.h> #define fi first #define se seco ...

  5. 写给.NET开发者的数据库Migration方案

    微软给我们提供了一种非常好用的数据库迁移方案,但是我发现周围的同学用的并不多,所以我还是想把这个方案整理一下..NET选手看过来,特别是还在通过手工执行脚本来迁移数据库的同学们,当然你也可以选择EF的 ...

  6. EF Core 数据库迁移(Migration)

    工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用  Pomelo.EntityFrameworkCore.MySql   源代码地址(https://github. ...

  7. Database first with EntityFramework (Migration)安装和升级

    最近看了国外几个项目,发现用EntityFramework做Code First的项目现在很流行. 最让我有兴趣的一个功能则是,EntityFramework对于数据库的安装和升级的无缝完美支持,且很 ...

  8. Squirrel: 通用SQL、NoSQL客户端

    安装 配置数据库 配置驱动 配置连接 如果你的工作中,需要使用到多个数据库,又不想在多种客户端之间切换来切换去.那么就需要找一款支持多数据库的客户端工具了.如果你要连接多个关系型数据库,你就可以使用N ...

  9. Laravel使用笔记 —— migration

    在使用 php artisan make:migration 创建migration时,可用 --path 指定创建migration文件的路径, 如果在执行的 php artisan migrate ...

随机推荐

  1. 错误号码1130:Host 'XXX' is not allowed to connect to this MySQL server

    今天在linux机器上装了一个mysql,想通过sqlyog远程连接过去,发生了:错误号码1130:Host 'XXX' is not allowed to connect to this MySQL ...

  2. JAVA面试常见问题之常见集合篇

    1.List 和 Set 区别 List 可以允许重复的对象. 可以插入多个null元素. 有序容器 Set 不允许重复的对象. 只能插入1个null元素 无序容器,可以使用TreeSet实现有序 2 ...

  3. TZ_01MyBatis_SqlMapConfig.xml

    1.sqlMapConfig的配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE conf ...

  4. Dockerfile 编写

    转: https://blog.fundebug.com/2017/05/15/write-excellent-dockerfile/如何编写最佳的Dockerfile 译者按: Dockerfile ...

  5. redis为什么快

    今天面试的时候被问到的一个问题,大致说了几点.回去又研究了一下. 大致分为几点: 1:Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快. ...

  6. Hystrix线程池配置

    Hystrix配置文件配置 断路器: hystrix.command.default.circuitBreaker.requestVolumeThreshold(当在配置时间窗口内达到此数量的失败后, ...

  7. JavaScript基本的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 用Python的pandas框架操作Excel文件中的数据教程

    用Python的pandas框架操作Excel文件中的数据教程 本文的目的,是向您展示如何使用pandas 来执行一些常见的Excel任务.有些例子比较琐碎,但我觉得展示这些简单的东西与那些你可以在其 ...

  9. element-ui表格列金额显示两位小数

    对于金额的显示,大多情况下需要保留两位小数,比如下面的(表格采用 element-ui): 在vue.js中,对文本的处理通常是通过设置一系列的过滤器,过滤器可以用在两个地方:双花括号插值 和 v-b ...

  10. AudioToolbox.framework框架学习

    http://quding0308.iteye.com/blog/1596710 AudioFile AudioFileStream类 提供了一个接口,用来解析一个流音频文件. //创建一个new s ...