zoukankan      html  css  js  c++  java
  • CF715E

    CF715E

    参考

    博主名字好听

    考虑没有(0)的情况,对每个(a_i ightarrow b_i)

    计环的个数为(m),那么(a,b)的距离为(n-m),易证

    再考虑题目

    建立(2n)个点,(p[1-n])表示位置,(v[1-n])表示数值

    对于(a_i eq 0,v_{a_i} ightarrow p_i),对于每个(b_i eq 0, p_i ightarrow v_{b_i})

    其中每个(v_x ightarrow p_y)表示补全后(a_y=x)(p_x ightarrow v_y)表示补全后(b_x=y)

    此时图中存在一些链和环,计环的数量为(c0),暂时不必考虑

    显然一条链或环,(p)点与(v)点交替出现

    定义四类链:

    (p)开头,(p)结尾的链,计数为(c1)

    (v)开头,(p)结尾的链,计数为(c2)

    (p)开头,(p)结尾的链,计数为(c3)

    (v)开头,(v)结尾的链,计数为(c4)

    环上要求(p,v)节点交替出现,先考虑(1,2,3)类链的连边方法

    (f_i)表示恰好有(i)个仅由(1)类链组成的环时,(1)类链出边的方案数

    (1)类链要么连向(1)类链,要么连向(3)类链

    我们发现恰好不好算,我们先设(f_i)保证有(i)个仅由(1)类链组成的环时,其他(1)类链出边随意选择的方案数

    可以枚举从(c1)中选出(j)条链排成(i)个环,剩下的(c_1-j)条链可以连向(1)类链或(3)类链

    得到方程

    [f_i=sumlimits_{j=0}^{c1}dbinom{c1}{j}egin{bmatrix}j\iend{bmatrix}A_{c1-j+c3}^{c1-j} ]

    那么再将(f_i)更新为恰好的方案数

    [f_i=f_i-sumlimits_{j=i+1}^{n}f_jdbinom{j}{i} ]

    (j)个环的方案书被重复计数(dbinom{j}{i})

    设g_i(表示恰好有)i$个仅由(2)类链组成的环时,(2)类链入边的方案数

    (f_i)求法

    (h=f*g)

    那么除了环和(4)类链,还有下面这(4)种长链

    (1.1)类链(^n ightarrow) (3)类链( ightarrow) (2)类链(^n)

    (2.1)类链(^n ightarrow) (3)类链

    (3.3)类链( ightarrow) (2)类链(^n)

    (4.3)类链

    有性质:

    (1.)只包含一条(3)类链

    (1.)开头和结尾都是(p)

    考虑用(4)类链和长链连接成环,环中长链和(4)类链一定交替出现

    (ans_i)为最终图中有(i)个环的方案数,那么枚举仅由(1)类链和(2)类链组成的环数(j)

    因为每条长链只包含一条(3)类链,所以给每条长链标号(1-c3)

    [ans_i=sumlimits_{j=0}^{i}h_j*egin{bmatrix}c3\j-iend{bmatrix}*c4! ]

    表示每条长链后先接一条(4)类链,再成环

    由于(c3=c4),所以长链后接(4)类链的方案数是(c4!)

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define int long long
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define lowbit(i) ((i)&(-i))
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=2010,p=998244353;
    	int n,t1,t2;
    	int fac[N],ifac[N],inv[N],ans[N],ret[N];
    	int f[N],g[N],h[N];
    	int a[N],b[N];
    	int nxt[N],deg[N];
    	bool vis[N];
    	int c0,c1,c2,c3,c4;
    	int c[N][N],s[N][N],A[N][N];
    	inline void init(int n)
    	{
    		s[0][0]=c[0][0]=A[0][0]=fac[0]=1;
    		for(int i=1;i<=n;++i)
    		{
    			fac[i]=fac[i-1]*i%p;
    			c[i][0]=A[i][0]=1;
    			for(int j=1;j<=i;++j)
    			{
    				c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
    				s[i][j]=(s[i-1][j-1]+(i-1)*s[i-1][j])%p;
    				A[i][j]=(A[i-1][j]+j*A[i-1][j-1])%p;
    			}
    		}
    	}
    	inline void work(int cnt,int *f)
    	{
    		for(int i=0;i<=cnt;++i)
    		{
    			for(int j=0;j<=cnt;++j)
    			{
    				f[i]=(f[i]+c[cnt][j]*s[j][i]%p*A[cnt-j+c3][cnt-j]%p);
    			}
    		}
    		for(int i=cnt;i>=0;--i)
    		{
    			for(int j=i+1;j<=cnt;++j)
    			{
    				f[i]=(f[i]-f[j]*c[j][i]%p+p)%p;
    			}
    		}
    	}
    	inline void dfs(int now,int s,int t)
    	{
    		vis[now]=1;
    		int to=nxt[now];
    		if(to)
    		{
    			if(vis[to]) ++c0;
    			else dfs(to,s,t^1);
    		}
    		else
    		{
    			if(!s&&t) ++c1;
    			else if(s&&!t) ++c2;
    			else if(s&&t) ++c3;
    			else ++c4;
    		}
    	}
    	inline void main()
    	{
    		n=read();init(n<<1);
    		for(int i=1;i<=n;++i) a[i]=read();
    		for(int i=1;i<=n;++i) b[i]=read();
    		for(int i=1;i<=n;++i)
    		{
    			if(a[i]) nxt[a[i]+n]=i,++deg[i];
    			if(b[i]) nxt[i]=b[i]+n,++deg[b[i]+n];
    		}
    		for(int i=1;i<=2*n;++i)
    			if(!vis[i]&&!deg[i]) dfs(i,i>n,i>n);
    		for(int i=1;i<=2*n;++i)
    			if(!vis[i]) dfs(i,i>n,i>n);
    		work(c1,f);work(c2,g);
    		for(int i=0;i<=n;++i)
    		{
    			for(int j=0;j<=i;++j)
    			{
    				h[i]=(h[i]+f[j]*g[i-j]%p)%p;
    			}
    		}
    		for(int i=0;i<=n;++i)
    		{
    			for(int j=0;j<=i;++j)
    			{
    				ans[i]=(ans[i]+h[j]*s[c3][i-j]%p*fac[c4]%p)%p;
    			}
    		}
    		for(int i=0;i<n;++i)
    			if(n-i-c0>=0) ret[i]=ans[n-i-c0];
    		for(int i=0;i<n;++i) printf("%lld ",ret[i]);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    
  • 相关阅读:
    华为网络工程师认证HCNP
    华为网络工程师认证HCNA——三层架构综合实验(详细)更新完毕
    华为网络工程师认证HCNA——两层架构综合实验(详细)
    华为网络工程师认证HCNA
    在VMware上装win 10
    命令帮助和文件管理命令
    《快活帮》第九次团队作业:Beta冲刺与验收准备
    《快活帮》第九次团队作业:【Beta】Scrum meeting 3
    《快活帮》第九次团队作业:【Beta】Scrum meeting 2
    《快活帮》第九次团队作业:【Beta】Scrum meeting 1
  • 原文地址:https://www.cnblogs.com/knife-rose/p/13055457.html
Copyright © 2011-2022 走看看