首页 > 其他分享 >P8329 [ZJOI2022] 树

P8329 [ZJOI2022] 树

时间:2024-12-24 15:41:59浏览次数:3  
标签:P8329 cup int sum 集合 ZJOI2022 include ll

设 \(f(S)\) 表示钦定第一颗树叶子集合为 \(S\) 的方案数,则有 \(f(S) = \prod\limits_{i=2}^{n} (i - 1 - \sum\limits_{j=1}^{i-1}[j \in S])\)。同理,设 \(g(T)\) 表示钦定第二颗树中叶子集合为 \(T\) 的方案数。

枚举第一颗树的叶子集合恰好为 \(S\),第二颗树的叶子集合恰好为 \(T\),直接容斥则有:

\[\begin{align} ans &= \sum_{S, T} \sum_{x \subseteq T} \sum_{y \subseteq S} (-1)^{|x|+|y|} f(S \cup x) g(T \cup y) \\ &= \sum_{S \cup T = U} (-2) ^ {|S \cap T|} f(S) g(T) \end{align} \]

\((2)\) 式已经可以直接 dp 计算了:从前往后依次给每个 \(i\) 分配:在 \(S\) 中 / 在 \(T\) 中 / 同时在 \(S\) 和 \(T\) 中即可。

设 \(f(i, s, t)\) 表示分配了 \([1,i]\),其中 \([1,i]\) 中有 \(s\) 个数在 \(S\) 中,\((i, n]\) 中还需要有 \(t\) 个数在 \(T\) 中的答案,转移容易,单次时间复杂度 \(\mathrm{O}(n^3)\)。

需要对 \([2, n]\) 分别做怎么办呢!这里有 \(n - i - t\) 的系数,不好一起做!但是把 \(s\) 和 \(t\) 改成不在 \(S\) 中和不在 \(T\) 中,系数就与 \(n\) 无关了,哈哈!

破防了。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
using ll = long long;
const int N = 510;
int MOD; ll f[N][N], g[N][N];
int main() {
	cin.tie(0)->sync_with_stdio(0);
	int N; cin >> N >> MOD;
	for(int t = 0; t <= N; ++t) f[0][t] = 1;
	for(int n = 1; n < N; ++n) {
		for(int s = 0; s <= n; ++s)
			for(int t = 0; t <= N - n + 1; ++t) if(f[s][t]) {
				ll x = n == 1 ? 1 : s;
				if(t) g[s][t - 1] = (g[s][t - 1] + f[s][t] * x % MOD * (t - 1)) % MOD;
				g[s + 1][t] = (g[s + 1][t] + f[s][t] * x % MOD * t) % MOD;
				g[s][t] = (g[s][t] + f[s][t] * x % MOD * t % MOD * (MOD - 2)) % MOD;
			}
		swap(f, g), memset(g, 0, sizeof(g));
		ll ans = 0;
		for(int s = 0; s <= n; ++s)
			for(int t = 0; t <= 1; ++t) if(f[s][t]) {
				if(t == 1) ans = (ans + f[s][t] * s) % MOD;
				if(!t) ans = (ans + f[s][t] * s) % MOD;
				if(!t) ans = (ans + f[s][t] * s % MOD * (MOD - 2)) % MOD;
			}
		printf("%lld\n", ans);
	}
	return 0;
}

标签:P8329,cup,int,sum,集合,ZJOI2022,include,ll
From: https://www.cnblogs.com/Aria-Math/p/18627830

相关文章

  • [ZJOI2022] 树
    [ZJOI2022]树一些经典的dp手法。考虑这个题目在讲什么,每个点都要朝左右两边连各一条有向边,限制是一个点要么左边没有入边要么右边没有入边,但不能两边同时没有入边。发现没法转化,考虑硬做。设\(f_{i,j,k,l}\)表示考虑前\(i\)个点,有\(j\)条向右的有向边终点待定,有\(......
  • P8329 [ZJOI2022] 树
    直接求是困难的,所以考虑容斥将所求容斥为两部分:每个结点至少在一棵树上为叶子的方案数-至少有一个结点在两棵树上都为叶子的方案数。考虑DP,设\(f_i(x,y)\)表示\([1,i]\)中是第一棵树的非叶子的结点数为\(x\),\([i+1,n]\)中是第二棵树的非叶子的结点数为\(y\)时的......
  • P8330 [ZJOI2022] 众数 题解
    Description给定一个长度为\(n\)的序列\(a_1,a_2,\dots,a_n\),问选一段区间,它的价值是里面的众数个数\(+\)外面的众数个数,求最大价值,以及所有满足这个最大价值的区间的外面的众数颜色。\(\sumn\leq5\times10^5,n\leq2\times10^5\)。Solution考虑根号分治。定义一个......
  • [ZJOI2022] 深搜 题解
    题目描述九条可怜是一个喜欢算法的女孩子,在众多算法中她尤其喜欢深度优先搜索(DFS)。有一天,可怜得到了一棵有根树,树根为\(\mathit{root}\),树上每个节点\(x\)有一个权值\(a_x\)。在一棵树上从\(x\)出发,寻找\(y\)节点,如果使用深度优先搜索,则可描述为以下演算过程:将递归栈......
  • [ZJOI2022] 树
    题目描述九条可怜是一个喜欢树的女孩子,她想生成两棵均有\(n\)个节点的树。第一棵树的生成方式是:节点\(1\)作为树的根。对于\(i\in[2,n]\),从\([1,i-1]\)......
  • 「ZJOI2022」众数
    「ZJOI2022」众数好难。题意:给定序列\(a\),选择一个连续子序列使得子序列内众数与剩下部分众数出现次数和最大,求出现次数和的最大值并给出剩下部分众数的可能情况。看到......
  • ZJOI2022 深搜
    链接:https://www.luogu.com.cn/problem/P8334题解:最小值期望显然可以转化为\(>=x\)的概率求和,所以我们可以考虑一个暴力,每次将\(>=x\)的点加入称为黑点,然后进行\(dp\)。那......