首页 > 其他分享 >「ARC140D」One to One - 题解

「ARC140D」One to One - 题解

时间:2022-10-24 20:33:36浏览次数:49  
标签:连通 int 题解 基环树 include ARC140D Mod

题解

若对每一块进行考虑,那么对于一个有 \(n\) 个点 \(n\) 条边的块,也就是基环树或环来说,里面一定不会存在 \(a_i=-1\)。否则就是一棵树了,那么也最多只会有一个 \(a_i=-1\)。

这意味着 $a_i =1 $ 所在的连通块一定是树,剩下的一定是环或基环树。且这些环或者基环树的贡献一定不会变,可以先加上。

于是只要考虑是树的块。首先如果树中的 \(-1\) 连向了一个环或者基环树,那么当前情况的贡献 \(f\) 是不变的。不考虑。所以只考虑树和树之间。于是设 \(g(j)\) 表示所有树合并后只剩下 \(j\) 个连通块的方案数。

转移显然有 \(g(j) \leftarrow g(j-1) \times sz_i\)。因为点 \(i\) 都是内部连边,会贡献一个新的连通块。最后算一下贡献就好了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=2000+5;
const int Mod=998244353;
struct edge{
	int v,nx;
}e[N<<1]; 
int n,ans,ne,cnt,f[N],a[N],pw[N],mul[N],sz[N],v[N],g[N];
bool vis[N];
void read(int u,int v)
{	e[++ne].v=v;
	e[ne].nx=f[u];
	f[u]=ne;
}
void dfs(int u)
{	vis[u]=1,sz[u]=1;
	for(int i=f[u];i;i=e[i].nx)
	{	int v=e[i].v;
		if(!vis[v])dfs(v),sz[u]+=sz[v];
	}
}
int main()
{	freopen("sum.in","r",stdin);
	freopen("sum.out","w",stdout);
	scanf("%d",&n);
	for(int i=pw[0]=mul[0]=1;i<=n;i++)mul[i]=1ll*mul[i-1]*i%Mod,pw[i]=1ll*pw[i-1]*n%Mod;
	for(int i=1;i<=n;i++)
	{	scanf("%d",&a[i]);
		if(a[i]!=-1)read(i,a[i]),read(a[i],i);
	}
	for(int i=1;i<=n;i++)
		if(a[i]==-1)dfs(i),v[++cnt]=sz[i];
	for(int i=1;i<=n;i++)
		if(!vis[i])dfs(i),ans=(ans+pw[cnt])%Mod;
	g[0]=1;
	for(int i=1;i<=cnt;i++)
		for(int j=i-1;j>=0;j--)g[j+1]=(g[j+1]+1ll*g[j]*v[i]%Mod)%Mod;
	for(int i=1;i<=cnt;i++)ans=(ans+1ll*g[i]*mul[i-1]%Mod*pw[cnt-i]%Mod)%Mod;
	printf("%d\n",ans);
	return 0;
}

标签:连通,int,题解,基环树,include,ARC140D,Mod
From: https://www.cnblogs.com/Rainy7/p/solution-at-arc140d.html

相关文章

  • [NOI Online #1 入门组] 跑步 题解
    [NOIOnline#1入门组]跑步题解一个经典问题:计数将正整数\(n\)拆分为若干个正整数的方案数,这里拆成的正整数是无序的,对\(P\)取模。容易得到\(O(n^2)\)解法设\(f_{i,j......
  • Codeforces Round #401 (Div. 2) 题解 (待续)
    AShellGame#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • April Fools Contest 2017 题解
    ANumbersJokeJoke数列,OEIS#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • Codeforces Round #402 (Div. 1) 题解(待续)
    AStringGame#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#define#defin......
  • BZOJ 4747-4749题解 Usaco2016 Dec
    BZOJ4747:[Usaco2016Dec]CountingHaybales给出N(1≤N≤100,000)个数,和Q(1≤Q≤100,000)个询问。每个询问包含两个整数A,B(0≤A≤B≤1,000,000,000)。对于每个询问,给出数值......
  • Codeforces Round #395 (Div. 1) 题解
    ATimofeyandatree#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#defin......
  • Spring常见问题解决办法汇总
     解决Theprefix'context'forelement'context:component-scan'isnotbound<beansxmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://w......
  • BSOJ7075题解
    感觉这一类DP至少不应该被叫做“LCS模型”,本质应该是其他的东西......先来考虑经典的LCS:\(dp[n][m]\)表示\(S[n]\)和\(T[m]\)匹配上的最长的长度。那么我们不妨......
  • GCJ 2017 R2 题解(待续)
    ProblemA.FreshChocolateProblemYouarethepublicrelationsmanagerforachocolatemanufacturer.Unfortunately,thecompany’simagehassufferedbecausecus......
  • 北方大学 ACM 多校训练赛 第四场 题解
    A.恶魔包毁灭世界已知一张二分图,问哪些边是二分图的可行边?先跑最小流,再把残余网络建图,几个重要结论是:·最小割的可行边(满流&&2点不在一个SCC中)·最小割的必行边(可行......