[计数] [容斥] P6277 [USACO20OPEN] Circus P
题意:
感性理解万岁!其实是太菜了 qwq。
首先有如下想法:
- 忽略标号,则所有状态互相可达。很显然。所以不妨让牛移动到
1\dots k 上。 - 对于两个位置
x,y ,若可以在不影响其他牛的情况下交换上面的牛,就连边x,y 。那么存在传递性,因为可以依次(x,y),(y,z),(x,y) 以做到(x,z) 。于是关系图是若干团,答案即为\frac {k!}{\prod s_i!} ,s_i 为团大小。 - “不影响其他牛”其实毫无意义,因为只需交换后倒置整个过程,即可消除影响。
现在考察两头牛
拓展一下,对于一条链
考察链在树上形态:在树上划出这些链,它们首尾相接,并且每条边恰被覆盖一次。
考察链在关系图上形态:称不满足条件的链为非法链,反之为合法链,合法链构成若干连通块,则每个连通块都在同一个团,又因为非法链的存在所以不同连通块在不同的团。
可能有一些团大小为
唯一的问题是怎么求出连通块对应的团的大小,直接统计貌似很困难。正难则反,转而用相接的非法链去刻画这个团,对于一条相接的非法链
这样算不重不漏,因为每一次相当于排除
于是团大小即为:
其中
时光倒流 set 维护即可。复杂度
当然可以精细实现
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5, mod = 1e9 + 7;
int n, u, v, du[N], rot, m, ans[N], jc[N], jcinv[N];
int fa[N], siz[N], cnt[N];
vector<int> to[N];
set<int> s;
struct dist{int x, y, w;};
vector<dist> jjdw[N];
inline int qstp(int a, int k) {int res = 1; for(; k; a = a * a % mod, k >>= 1) if(k & 1) res = res * a % mod; return res;}
inline void dfs(int u, int from, int lst, int len){
if(du[u] == 2){
for(auto v : to[u]) if(v ^ from) dfs(v, u, lst, len + 1);
}
else{
fa[u] = u, siz[u] = 1, s.insert(u);
if(lst) jjdw[len].push_back({u, lst, len}), ++cnt[u], ++cnt[lst];
for(auto v : to[u]) if(v ^ from) dfs(v, u, u, 2);
}
}
inline int find(int u) {return fa[u] == u ? u : fa[u] = find(fa[u]);}
inline void mer(int x, int y, int w){
int fx = find(x), fy = find(y);
fa[fx] = fy;
siz[fy] += siz[fx] + w - 2;
cnt[fy] += cnt[fx] - 2;
s.erase(fx);
}
signed main(){
jc[0] = jcinv[0] = 1;
for(int i = 1; i < N; ++i) jcinv[i] = qstp(jc[i] = jc[i - 1] * i % mod, mod - 2);
cin >> n;
for(int i = 1; i < n; ++i){
scanf("%lld%lld", &u, &v);
to[u].push_back(v), to[v].push_back(u);
++du[u], ++du[v];
}
for(int i = 1; i <= n; ++i) if(du[i] == 1) rot = i;
dfs(rot, 0, 0, 0);
ans[n] = jc[n];
for(int k = n - 1; k; --k){
for(auto _ : jjdw[n - k - 1]) mer(_.x, _.y, _.w);
ans[k] = jc[k];
for(auto i : s){
int mb = k - ((k - n + 1) * cnt[i] + n - siz[i]);
ans[k] = ans[k] * jcinv[mb] % mod;
}
}
for(int i = 1; i <= n; ++i) printf("%lld\n", ans[i]);
return 0;
}