• [JSOI2019] 神经网络


    一、题目

    点此看题

    二、解法

    有一个神奇的题意转化:我们把每一棵树划分成若干条链,因为不同的树任意两点之间都有边,所以我们把这些链任意连接就形成哈密顿回路,要求是相邻的链必须来自不同的树。

    首先我们考察把树划分成 \(i\) 条链的方案数 \(f_i\),可以直接树背包,在确定一条链并且这条链非单点的时候乘上 \(2\) 的系数。

    然后考虑怎么把链任意连接,可以写出以链数为标记的 \(\tt EGF\),那么答案的 \(\tt EGF\) 就是所有树 \(\tt EGF\) 的卷积。由于第一棵树是不一样的,我们先考虑写出其他树的 \(\tt EGF\)

    \[\sum_{i=1}^n f_i\cdot i!\sum_{j=1}^i(-1)^{i-j}\cdot {i-1\choose i-j}\cdot \frac{x^j}{j!} \]

    首先是把这些链任意排列的方案数,即 \(f_i\cdot i!\);由于还有相邻链必须来自不同树的限制,所以要容斥。我们枚举最后形成了 \(j\) 条大链(相邻的同色链缩合在一起),那么就有 \(i-j\) 个空隙需要拼合,方案数是 \({i-1\choose i-j}\),容斥系数是 \((-1)^{i-j}\)

    考虑写出第一棵树的 \(\tt EGF\),额外的限制是:起点必须是 \(1\) 号点。那么我们把 \(1\) 号点所在的链放在首位就行了,并且让它不参与和其他树 \(\tt EGF\) 的合并:

    \[\sum_{i=1}^n f_i\cdot (i-1)!\sum_{j=1}^i(-1)^{i-j}\cdot {i-1\choose i-j}\cdot \frac{x^{j-1}}{(j-1)!} \]

    还有一个限制是:最后一条链不能是第一棵树的链,那么我们减去这种情况即可,可以强制一条链放在最后,让它不参与和其他树 \(\tt EGF\) 的合并,所以要减去这样的 \(\tt EGF\)

    \[\sum_{i=1}^nf_i\cdot (i-1)!\sum_{j=2}^i (-1)^{i-j}\cdot{i-1\choose i-j}\cdot\frac{x^{j-2}}{(j-2)!} \]

    暴力实现卷积,时间复杂度 \(O(n^2)\)

    #include <cstdio>
    #include <vector>
    #include <iostream>
    using namespace std;
    const int M = 5005;
    const int MOD = 998244353;
    #define int long long
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int T,n,m,siz[M],dp[M][M][2],t[M][3];
    int ans,fac[M],inv[M],f[M],g[M],z[M];
    vector<int> e[M];
    void add(int &x,int y) {x=(x+y)%MOD;}
    void init(int n)
    {
    	fac[0]=inv[0]=inv[1]=1;
    	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD;
    	for(int i=2;i<=n;i++) inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
    	for(int i=2;i<=n;i++) inv[i]=inv[i-1]*inv[i]%MOD;
    }
    int C(int n,int m)
    {
    	if(n<m || m<0) return 0;
    	return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
    }
    void dfs(int u,int fa)
    {
    	dp[u][0][0]=siz[u]=1;
    	for(int v:e[u]) if(v^fa) dfs(v,u);
    	for(int v:e[u]) if(v^fa)
    	{
    		for(int i=0;i<siz[u];i++)
    			for(int j=1;j<=siz[v];j++)
    			{
    				add(t[i+j][0],dp[u][i][0]*dp[v][j][0]);
    				add(t[i+j][1],dp[u][i][1]*dp[v][j][0]);
    				add(t[i+j][1],dp[u][i][0]*dp[v][j][1]);
    				add(t[i+j-1][2],dp[u][i][1]*dp[v][j][1]*2);
    				add(t[i+j][2],f[i]*dp[v][j][0]);
    			}
    		siz[u]+=siz[v];
    		for(int i=0;i<siz[u];i++)
    		{
    			dp[u][i][0]=t[i][0];
    			dp[u][i][1]=t[i][1];
    			f[i]=t[i][2];
    			t[i][0]=t[i][1]=t[i][2]=0;
    		}
    		for(int j=0;j<=siz[v];j++)
    			dp[v][j][0]=dp[v][j][1]=0;
    	}
    	for(int i=siz[u];i>=1;i--)
    	{
    		dp[u][i][0]=(dp[u][i-1][0]+f[i]+dp[u][i][1]*2)%MOD;
    		dp[u][i][1]=(dp[u][i-1][0]+dp[u][i][1])%MOD;
    		f[i]=0;
    	}
    	e[u].clear();
    }
    void work()
    {
    	n=read();static int start=1;
    	for(int i=1;i<n;i++)
    	{
    		int u=read(),v=read();
    		e[u].push_back(v);
    		e[v].push_back(u);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;i++) f[i]=0;
    	if(start)
    	{
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=i;j++)
    			{
    				int t=dp[1][i][0]*fac[i-1]%MOD*C(i-1,i-j)
    				%MOD*inv[j-1]%MOD;
    				if((i-j)&1) add(f[j-1],MOD-t);
    				else add(f[j-1],t);
    				if(j>1)
    				{
    					t=t*(j-1)%MOD;
    					if((i-j)&1) add(f[j-2],t);
    					else add(f[j-2],MOD-t);
    				}
    			}
    		start=0;
    	}
    	else
    	{
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=i;j++)
    			{
    				int t=dp[1][i][0]*fac[i]%MOD*C(i-1,i-j)
    				%MOD*inv[j]%MOD;
    				if((i-j)&1) add(f[j],MOD-t);
    				else add(f[j],t);
    			}
    	}
    	for(int i=0;i<=m;i++)
    		for(int j=0;j<=n;j++)
    			add(z[i+j],f[j]*g[i]);
    	m+=n;
    	for(int i=0;i<=m;i++)
    		g[i]=z[i],z[i]=0;
    	for(int i=0;i<=n;i++)
    		dp[1][i][0]=dp[1][i][1]=f[i]=0;
    }
    signed main()
    {
    	T=read();init(5000);g[0]=1;
    	while(T--) work();
    	for(int i=0;i<=m;i++) add(ans,g[i]*fac[i]);
    	printf("%lld\n",ans);
    }
    
  • 相关阅读:
    【秒杀系统】零基础上手秒杀系统(三):抢购接口隐藏 + 单用户限制频率
    【秒杀系统】零基础上手秒杀系统(二):令牌桶限流 + 再谈超卖
    【秒杀系统】从零开始打造简易秒杀系统(一):防止超卖
    EditPlus快捷键
    ant的安装及项目的发布
    Java 中类型转换
    navicat 结合快捷键
    go中安装Beego不成功笔记
    Excel中添加下拉框
    在Excel中把横行与竖列进行置换、打勾号
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/16371128.html
Copyright © 2020-2023  润新知