首页 > 其他分享 >[ABC303Ex] Constrained Tree Degree 题解

[ABC303Ex] Constrained Tree Degree 题解

时间:2024-02-27 22:15:37浏览次数:20  
标签:md int 题解 Tree ntt mxn fac Constrained define

如果每个点的度数都知道了,那问题就转化成了 P2290 [HNOI2004]树的计数,直接求 Prufer 序列的个数即可,因为一个度数为 \(d_i\) 的点在 Prufer 序列中的出现次数是 \(d_i-1\),所以答案是:\(\frac{(n-2)!}{\prod_{i=1}^{n}(d_i-1)!}\)。

可以把 \((n-2)!\) 放到最后再乘,变一下:

\[\prod_{i=1}^{n}\frac{1}{(d_i-1)!}\times (n-2)! \]

这题要求 \(d_i\in S\),发现前面这个东西可以用母函数来做。

令 \(F(x)=a_0+a_1x+a_2x^2+\dots+a_{n-2}x^{n-2}\),对于每个 \(i\in S\),令 \(a_{i-1}=\frac{1}{(i-1)!}\),其余的 \(a_i=0\)。

可以用多项式快速幂求出 \(F(x)^n\),然后答案就是 \(x^{n-2}\) 对应的系数乘上 \((n-2)!\)。

时间复杂度:\(O(n\log^2 n)\),可以通过本题。

注意清空多余的系数

代码:

#include<bits/stdc++.h>
#define int long long
#define mxn 1000003
#define md 998244353
#define pb push_back
#define mkp make_pair
#define ld long double
#define umap unordered_map
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
#define pq priority_queue
using namespace std;
int n,k,c,s,a[mxn],f[mxn],g[mxn],fac[mxn],ifac[mxn],rev[mxn];
int power(int x,int y){
	int ans=1;
	for(;y;y>>=1){
		if(y&1)ans=ans*x%md;
		x=x*x%md;
	}
	return ans;
}
void ntt(int *a,int n,int flag){
	rept(i,0,n)if(i<rev[i])swap(a[i],a[rev[i]]);
	for(int h=1;h<n;h<<=1){
		int x,y,s=power(3,499122176/h);
		for(int j=0;j<n;j+=h<<1){
			int w=1;
			for(int k=j;k<j+h;++k){
				x=a[k],y=w*a[k+h]%md;
				a[k]=(x+y)%md;
				a[k+h]=(x-y+md)%md;
				w=w*s%md;
			}
		}
	}
	if(flag==-1){
		int p=power(n,md-2);
		reverse(a+1,a+n);
		rept(i,0,n)a[i]=a[i]*p%md;
	}
}
void power(int x){
	g[0]=1;
	for(;x;x>>=1){
		if(x&1){
			ntt(f,s,1);
			ntt(g,s,1);
			rept(i,0,s)g[i]=g[i]*f[i]%md;
			ntt(g,s,-1);
			ntt(f,s,-1);
			rept(i,n-1,s)g[i]=0;
		}
		ntt(f,s,1);
		rept(i,0,s)f[i]=f[i]*f[i]%md; 
		ntt(f,s,-1);
		rept(i,n-1,s)f[i]=0;
	}
}
signed main(){
	scanf("%lld%lld",&n,&k);
	fac[0]=1;
	rep(i,1,n)fac[i]=fac[i-1]*i%md;
	ifac[n]=power(fac[n],md-2);
	drep(i,n,1)ifac[i-1]=ifac[i]*i%md; 
	rep(i,1,k)scanf("%lld",&a[i]),f[a[i]-1]+=ifac[a[i]-1];
	for(c=0,s=1;s<=n<<1;s<<=1,++c);
	rept(i,0,s)rev[i]=(rev[i>>1]>>1)|((i&1)<<(c-1));
	power(n);
	cout<<g[n-2]*fac[n-2]%md;
	return 0;
}

标签:md,int,题解,Tree,ntt,mxn,fac,Constrained,define
From: https://www.cnblogs.com/zifanoi/p/18038516

相关文章

  • [COI2009] PLAHTE 题解
    首先对于每一个矩形,若\(x_2<0\),就将\(x_1,x_2\)均乘上\(-1\)再交换,对于\(y_1,y_2\)也做同样的操作。我们建立一个操作序列a[0~1000],和一个数组\(d\),每一个操作用\((x,y)\)表示,就是在\(d\)内把所有\(0\)到\(x\)的位置加上\(y\)。我们再定义一种新的操作\([x,y......
  • [USACO11NOV]Binary Sudoku G 题解
    定义一个\(3\times3\)的表格\(a\),表示每个小九宫格内1的个数的奇偶状态。再定义两个长为\(9\)的数组\(c0,c1\),表示每行每列上1的个数的奇偶状态。当\(d_{i,j}\)取反时,会将\(a_{[\frac{i}{3}],[\frac{j}{3}]},c0_i,c1_j\)各取反一次。要将\(a_{i,j}\)全部变为0......
  • [ABC286Ex] Don't Swim 题解
    我们首先求出线段与多边形的交点,如果交点个数\(<2\)或者有无数个交点,则可以直接输出\(S\)到\(T\)之间的距离。接下来我们考虑交点个数为\(2\)的情况。为了方便,我们记距离\(S\)最近的那个交点为\(P_1\),远的为\(P_2\)。举个例子:在这个例子中,直线\(ST\)将整个多边......
  • P3577 [POI2014]TUR-Tourism 题解
    考虑在无向图上进行dfs,可以得到很多棵dfs树(因为图不一定连通),这些树形成了一个森林。然后由任意两点间不存在节点数超过\(10\)的简单路径这个限制可以得出这些树的深度都不超过\(10\),然后可以想到树上状压dp。有一个重要的性质,就是无向图dfs树上的非树边,一定是回边,所以......
  • CF516E Drazil and His Happy Friends 题解
    题目传送门记\(d=\gcd(n,m)\),发现只有编号在模\(d\)意义下相同的人之间会产生影响,那么有解当且仅当每个剩余系内有至少一个人是快乐的。所以在\(d>b+g\)时直接输出-1即可。对于剩下的情况,先令\(n\leftarrow\fracnd,m\leftarrow\fracmd\),如果\(n<m\)那么把男女交......
  • [ARC140F] ABS Permutation (Count ver.) 题解
    洛谷题面传送门AT题面传送门发现不太好直接求,考虑将\(P\)映射到\(P^{-1}\)上,这样题目中的条件就变成了\(|P_i-P_{i+M}|=1\)。因此我们可以对模\(M\)的每个剩余系做\(M=1\)的情况,然后最后快速幂合并。考虑\(M=1\)的情况怎么做。记\(f_i\)表示\(K=i\)的方案数,......
  • [ARC112F] Die Siedler 题解
    题目传送门人类智慧题。发现\(2\)操作肯定是不劣的,所以能换则换。考虑将手上的牌转换成一个多进制的数,这样\(2\)操作就是其进位方法,\(1\)操作就是将当前的数加上牌包对应的数,答案就是其各位数字之和,不难发现其值为:\[\sum_{i=1}^nc_i\times2^{i-1}\times(i-1)!\]再考......
  • 2024.2.27模拟赛T2题解
    题目有一个神奇的结论\(\foralla<b<c,a\oplusc>min(a\oplusb,b\oplusc)\)然后就可以写出\(n^2\)dp,再用TRIE树优化即可code#include<bits/stdc++.h>usingnamespacestd;#defineN200005#defineintlonglongintn,k1,k2;inta[N],fl[2];constintm......
  • CF1392I Kevin and Grid 题解
    题目传送门\(\large\textbf{Statement.}\)给定两个序列\(a,b\),有一个\(n\timesm\)的网格图,每个点\((i,j)\)上有个权值\(a_i+b_j\),每个点和其上、下、左、右方相邻的点有连边。多次询问,每次给一个阈值\(x\),将图分为权值\(<x\)(蓝色)和\(\gex\)(红色)的两种连通块。一......
  • P10084 [GDKOI2024 提高组] 计算 题解
    题目传送门前置知识:单位根反演先考虑怎么求\(F(x,a,b)\),易得\(\gcd(x^a-1,x^b-1)=x^{\gcd(a,b)}-1\)。所以\(L=m^{\gcd(a,b)}+1,R=m^{\gcd(c,d)}\),然后发现\([L,R]\)中的数模\(m\)后每种余数出现次数相同,下面记其为\(n=\frac{R-L}{m}\)。考虑用生成函数做,易得答案为......