Idea

随便想的,来源出自读错题。如果有原或者觉得我的sol错了可以评论或私信。

1:

\(n\) 个点的无根树,每次可以选一个非空联通块删掉,要求删掉这个联通块后剩余部分仍然联通。对于所有 \(k \in [1,n]\),求有多少种方案恰好 \(k\) 次操作后删空。\(n \le 500\)

solution

先划分联通块,然后相当于每次选一个叶子删掉。

无根树可以先钦定根,发现每一种方案都被算了根所在联通块大小次,利用点边容斥使这个联通块的系数变成 \(1\)

复杂度 \(O(n^3)\)

未经验证的代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=410,mod=1e9+7;
vector<int> e[N];
int sz[N];
PII E[N];
int C[N][N];
int f[N][N];
int g[N];
int Ans[N];
int n;

void init(int n)
{
	for(int i=0;i<=n;i++)
	{
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
	}
}

void Add(int &a,int b)
{
	if(a+b>=mod) a=a-mod+b;
	else a=a+b;
}

void Dp(int u,int p,int t=0)
{
	memset(f[u],0,sizeof f[u]);
	f[u][0]=1;
	sz[u]=0;
	for(auto v:e[u])
	{
		if(v==p) continue;
		Dp(v,u);
		memset(g,0,sizeof g);
		for(int j=0;j<=sz[u];j++)
		{
			for(int k=0;k<=sz[v];k++)
			{
				Add(g[j+k],f[u][j]*f[v][k]%mod*C[j+k][k]%mod);
			}
		}
		memcpy(f[u],g,sizeof g);
		sz[u]+=sz[v];
	}
	memset(g,0,sizeof g);
	for(int j=0;j<=sz[u];j++) 
	{
		if(t!=2) Add(g[j],f[u][j]);
		if(t!=1) Add(g[j+1],f[u][j]);
	}
	sz[u]+=1;
	memcpy(f[u],g,sizeof g);
}

signed main()
{
	// freopen("1.in","r",stdin);
	// freopen("1.out","w",stdout);

	cin>>n;
	init(n);
	for(int i=1,a,b;i<n;i++)
	{
		cin>>a>>b;
		e[a].push_back(b);
		e[b].push_back(a);
		E[i]={a,b};
	}

	for(int i=1;i<=n;i++)
	{
		Dp(i,0,2);
		for(int j=1;j<=n;j++) Add(Ans[j],f[i][j]);
	}

	for(int i=1;i<n;i++)
	{
		int a=E[i].first,b=E[i].second;
		Dp(a,b,1),Dp(b,a,1);
		for(int j=0;j<=sz[a];j++)
		{
			for(int k=0;k<=sz[b];k++)
			{
				Add(Ans[j+k+1],mod-f[a][j]*f[b][k]%mod*C[j+k][j]%mod);
			}
		}
	}

	for(int i=1;i<=n;i++) cout<<Ans[i]<<"\n";

	return 0;
}

2:

\(n\) 个点的有根树,所有边的方向从祖先指向儿子。
\(m\) 次询问,每次添加一条有向边 \((u,v)\),问你合法拓扑序个数。
\(n \le 1e5,q \le 100\)

solution(正确性未知)

首先外向树的合法拓扑序个数是容易的,这个等于 \(\frac{n!}{\prod sz_i}\)

添加一条边,相当于要求了这两个点的先后关系,我们求出这个的概率乘上树合法拓扑序个数即可。

这个概率相当于从 LCA 开始,如果扩展的点不在这两个儿子的方向,不管。否则就是更靠近某个儿子一步。

可以认为有两个栈,每次等概率弹掉一个栈顶,问某个栈先空的概率。

直接 dp:\(f_{i,j}=\frac{f_{i-1,j}+f_{i,j-1}}{2}\).

其中 \(f_{0,i}=1\)

不知道能不能做到比 \(O(min(n^2,nq))\) 好?

posted @ 2025-04-08 11:41  Richard_whr  阅读(21)  评论(0)    收藏  举报