首页 > 其他分享 >炫酷反演魔术?

炫酷反演魔术?

时间:2022-11-01 07:55:06浏览次数:53  
标签:ch 魔术 int MAX ret 反演 1ll 炫酷 define

记录一些自己做的简单题。

P6478

简单容斥。设 \(f[x][i]\) 表示 \(x\) 为根子树,钦定 \(i\) 对祖孙关系的方案数。

可以用树形背包转移。(顺便给我科普了真正正确的树形背包写法。)

然后可以把根对孩子的贡献加入。

\(f[x][i+1] += f[x][i] \cdot (s-i)\)。

\(s\) 表示子树内与 \(x\) 颜色相反的节点个数。(从剩下的未匹配点中选一个匹配。)

然后恰好的方案数就是 $g[k] = \sum_{i=k}^{m = n/2} (-1)^{i-k} \binom{i}{k}f[1][i] (m-i)!@

这里阶乘表示剩下 \(m-i\) 个点对放任自流。

#include <bits/stdc++.h>
#include <assert.h>
using namespace std;
typedef long long ll;
#define ep emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define fin freopen("in.in","r",stdin);
inline int read() {
	int x=0, v=1,ch=getchar();
	while('0'>ch||ch>'9') {
		if(ch=='-') v=0;
		ch=getchar();
	}while('0'<=ch&&ch<='9') {
		x=(x*10)+(ch^'0');
		ch=getchar();
	}return v?x:-x;
}
const int MAX = 5005,P=998244353;
int n, m;
string a;
vector<int>G[MAX];

int fac[2505],inv[2505];
int siz[MAX], s[2][MAX], gg[MAX] , f[MAX][2505]; // 钦定 x 子树内 i 个事件 
void inc(int &x,int y){
	x+=y;if(x>=P)x-=P; 
}
void dfs(int x,int fa) {
	siz[x] = 1, s[a[x]&15][x] = 1;
	f[x][0] = 1;
	for(int y:G[x]) {
		if(y==fa) continue;
		dfs(y, x);
		for(int i=0;i<=min(m,siz[x]+siz[y]);++i) gg[i] = 0;
		for(int i=0;i<=min(m,siz[x]);++i) {
			for(int j=0;j<=min(m,siz[y]);++j) {
				inc(gg[i+j], 1ll * f[x][i] * f[y][j] % P);
			}
		}
		siz[x]+=siz[y];
		for(int i=0;i<=min(m, siz[x]);++i) f[x][i] = gg[i];
		s[0][x]+=s[0][y], s[1][x]+=s[1][y];
	}
	for(int i=min(m, siz[x]+1);i;--i) {
		inc(f[x][i], 1ll * f[x][i-1] * max(0, s[( a[x] & 15 )^ 1][x] - i + 1) % P);
	}	
}
int C(int n,int m){
	return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;
}
int qpow(int x,int p){
	int ret=1;
	for(;p;p>>=1,x=1ll*x*x%P)if(p&1)ret=1ll*ret*x%P;
	return ret;
} 
signed main() { 
	n = read();
	
	m = n >> 1;
	
	fac[0]=1;
	for(int i=1;i<=m;++i)fac[i]=1ll*fac[i-1]*i%P;
	inv[m]=qpow(fac[m],P-2);
	for(int i=m;i>=1;--i)inv[i-1]=1ll*inv[i]*i%P;
	
	cin >> a; a = ' ' + a;
	for(int i=1;i<n;++i) {
		int u,v;
		u = read(),v = read();
		G[u].ep(v), G[v].ep(u);
	}
	dfs(1,0);
	
	
	for(int i=0;i<=m;++i)f[1][i]=1ll*f[1][i]*fac[m-i]%P;
	for(int i=0;i<=m;++i) {
		int ans=0;
		for(int j=i;j<=m;++j){
			inc(ans,1ll * ((j-i&1) ? P-1 : 1) * f[1][j] % P * C(j,i) % P);
		}
		printf("%d\n",ans);
	}
	return 0;
}

标签:ch,魔术,int,MAX,ret,反演,1ll,炫酷,define
From: https://www.cnblogs.com/Lates/p/16846501.html

相关文章

  • 那些你不知道的炫酷导航交互效果
    基于上次发布的那些你不知道的炫酷按钮交互效果反馈比较好,后续将继续收集那些炫酷的交互效果,希望可以给你的项目添砖加瓦,更上一层楼。那些你不知道的炫酷交互效果系列:......
  • 单位根反演
    单位根反演就是下面这个式子:\[[n|k]=\frac{1}{n}\sum_{i=0}^{n-1}w_n^{ik}\]证明:当\(n|k\)时,\(w_n^{ik}=1\),原式成立。当\(n\not{|}k\)时,原式等于\(\frac{1}{n......
  • 莫比乌斯反演
    线性筛莫比乌斯函数intss[N+5],mu[N+5],cnt,sum[N+5];boolvs[N+5];ilvoidinit(intn){for(riunsignedinti=2;i<=n;++i){if(!vs[i])ss[++cnt]=i,......
  • 拉格朗日反演推导扩展Cayley公式
    萌新初学拉格朗日反演,这个看起来很对所以应该是对的吧?把\(n\)个点连成有\(k\)棵树的森林,并且要求\(1,2,\cdots,k\)这\(k\)个点两两不在同一棵树的方案数。首先......
  • bzoj 2301: [HAOI2011]Problem b mobius反演 RE
    ​​http://www.lydsy.com/JudgeOnline/problem.php?id=2301​​设f(i)为在区间[1,n]和区间[1,m]中,gcd(x,y)=i的个数。设F(i)为在区间[1,n]和区间[1,m]中,gcd(x,y)%......
  • 【Coel.学习笔记】莫比乌斯反演
    闲话记得在差不多一年前写扩展欧拉定理的时候我提了一句这周终于把古代猪文搞定了,数论这块的内容就只剩个博弈论了别提莫比乌斯反演之类的东西,我不想搞甚至刚开始写......
  • Python最会变魔术的魔术方法,我觉得是它!
    在​​上篇文章中​​,我有一个核心的发现:Python内置类型的特殊方法(含魔术方法与其它方法)由C语言独立实现,在Python层面不存在调用关系。但是,文中也提到了一个例外:一个非......
  • PS新手教程--如何使用ps制作炫酷的封面效果
    如何使用ps制作炫酷的封面效果?给大家介绍如何使用ps制作炫酷的封面效果,一起来看看吧。炫酷的封面效果图如下1、打开ps,新建一个任意尺寸的图像并文字。2、创建新一个空白的图......
  • 【JS设计模式笔记】神奇的魔术师-简单工厂模式(创建型)
    简单工厂模式(SimpleFactory):又叫静态工厂方法,由一个工厂对象决定创建某一种产品对象类的实例。主要用来创建同一类对象。第一次需求开发一个登录模块的需求,用户名输入框......
  • 成品直播源码推荐,平台实现的炫酷背景页面
    成品直播源码推荐,平台实现的炫酷背景页面  <!DOCTYPEHTML><html><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><title>运营系统登录页......