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. JDBC连接整个过程

    1.导入驱动(放在lib下) connector-java-5.0.8-bin.jar 2.导入配置文件(放在src下) jdbc.properties driverClass=com.mysql.j ...

  2. [转]文件file属性详解

    不能直接访问用户计算机中的文件,一直都是Web应用开发中的一大障碍.2000年以前,处理文件的唯一方式就是在表单中加入<input type="file">字段,仅此而 ...

  3. bootstrap-fileinput详细说明与使用

    介绍 bootstrap-fileinput是一款非常优秀的HTML5文件上传插件,支持文件预览.多文件上传等一系列特性. 一款非常优秀的HTML5文件上传插件,支持bootstrap 3.x 和4. ...

  4. Mybatis 框架搭建实例

    前言 MyBatis是一个优秀的持久层框架.原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等).框架的作用就是把这些繁琐的代码封装. MyBatis通 ...

  5. “Bootstrap做的响应式菜单在iPhone上点击不了二级菜单“的解决办法!

    只需把把点击的a(被点击的)变成button即可.

  6. JavaScript 面试:什么是纯函数?

    原文:Eric Elliott  译文:众成翻译 www.zcfy.cc/article/master-the-javascript-interview-what-is-a-pure-function ...

  7. org.openqa.selenium.ElementNotInteractableException: element not interactable

    F12查看元素确实存在的 有人说延长加载时间 webDriver.manage().timeouts().implicitlyWait(, TimeUnit.SECONDS); // 等待5秒加载完成 ...

  8. springmvc java程序文件保存地址的路径问题

    会保存为这种斜杠 不论之前填写的是什么样

  9. Web三大组件之控制器组件Servlet(转载)

    Servlet:主要用于处理客户端传来的请求,并返回响应.获取请求数据>处理请求>完成响应 过程:客户端发送请求----HTTP服务器接收请求,HTTP服务器只负责解析静态HTML界面,其 ...

  10. vue前后端分离

    axios前后端交互 安装 一定要安装到`项目目录下 cnpm install axios 配置 在main.js中配置 //配置axios import axios from 'axios' Vue ...