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. html 输入框显示“小叉叉”的清空方法

    在IE10以下,我们的输入框input会出现小叉叉.怎么解决这个问题呢? 针对input框我们做一个处理 <style type="text/css"> input:: ...

  2. 关于在静态html中实现语言切换的思路与实现

    在项目中只用到了三种语言:英文.中文简体.中文繁体.所以我首先想到了最笨的方法:1.直接将三种语言写在html中,显示当前设置的语言隐藏其它两种来实现.2.使用css伪元素的content:attr( ...

  3. 图像通道、Scalar、分离、合成通道

    http://lib.csdn.net/article/opencv/33264 http://blog.csdn.net/laohu_tiger/article/details/17359777 h ...

  4. Django项目:CRM(客户关系管理系统)--34--26PerfectCRM实现King_admin自定义排序

    ordering = ['-qq'] #自定义排序,默认'-id' #base_admin.py # ————————24PerfectCRM实现King_admin自定义操作数据———————— f ...

  5. 微信小程序滚动到某个位置添加class效果。

    <scroll-view scroll-y="true" style="height:100vh;" bindscrolltoupper="up ...

  6. 建筑设计类软件整理ACDSee,PS,CAD,Ecotect,SketchUp,Phoenics,Revit,Rhino,

    关于建筑设计类软件整理 1 建筑设计类专业最常用软件如下,包括SU,CAD, REVIT,PS等. 2 sketch up 简称SU,中文名草图大师,在推敲方案,拉推体块时有着不可或缺的作用,而且随着 ...

  7. Appium_Python_Client介绍

    一.Appium_Python_Client介绍 Appium的实用方法都藏在Client的源码里,对于driver和webelement实例,均有对应的元素查找方法(webelement查找的是下面 ...

  8. 开始使用Apache弗林克和Mapr Streams

    Introduction MapR Ecosystem Package 2.0 (MEP) is coming with some new features related to MapR Strea ...

  9. redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法

    redis范围查询应用. 需求 根据IP找到对应的城市 原来的解决方案 oracle表(ip_country): 查询IP对应的城市: 1.把a.b.c.d这样格式的IP转为一个数字,例如为把210. ...

  10. H5C3--sessionStorage和localStorage的使用

    一.sessionStorage的使用 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...