CF 1528E

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 1528E相关的知识,希望对你有一定的参考价值。

  • 度数均小于 \\(3\\) 则是条链,必然可以选出一个结点作为根,形成内向树或外向树 。(1)

  • 否则若 \\(deg_u = 3\\)

    • \\(u\\) 的边方向唯一,则形成以 \\(u\\) 为根的内向树或外向树。(1)

    • 若存在 \\(deg_v = 3, u \\neq v\\),它们的边不完全相同,

      则树必然由一棵外向树和一棵内向树用一条链串起来,且两个树的根度数为 \\(2\\)(2)

    • 否则,是一个外向树或内向树。(1)

  • 然后可以通过递推求出 \\(f_i\\): 直径为 \\(i\\) 的外向树每个点度数不超过 \\(2\\) 的方案数。

  • 对于 (1),最后根结点度数可以为 \\(3\\),特别计算一下然后乘以 \\(2\\) (内向树对应外向树) 减去 \\(1\\) (单链重复计算)。

  • 对于 (2),枚举外向树的直径,然后通过前缀和可以快速计算。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10, mod = 998244353;

int fpow_(int a, int b, int res = 1) {
	for (; b; b >>= 1, a = 1ll*a*a%mod)
		if (b&1)
			res = 1ll*res*a%mod;
	
	return res;
}

int n, i2 = fpow_(2, mod - 2), i6 = fpow_(6, mod - 2), ans, f[N], g[N], h[N];

int cal_(int x, int k) {
	if (k == 2) 
		return 1ll*x*(x + 1)%mod*i2%mod;
	
	return 1ll*x*(1ll*x*(x + 3)%mod + 2)%mod*i6%mod;
}

int main() {
	scanf("%lld", &n), n++;
	
	f[0] = g[0] = 1;
	
	for (int i = 1; i <= n; i++) {
		f[i] = (cal_(g[i - 1], 2) - cal_(g[i - 1] - f[i - 1], 2))%mod;
		g[i] = (g[i - 1] + f[i])%mod, h[i] = (1ll*h[i - 1] + f[i] - f[i - 1])%mod;
	}
	
	ans = 2ll*(cal_(g[n - 1], 3) - cal_(g[n - 1] - f[n - 1], 3))%mod - 1;
	
	for (int i = 2; i <= n - 2; i++)
		ans = (ans + 1ll*(f[i] - f[i - 1])*h[n - i])%mod;
	
	printf("%d\\n", (ans + mod)%mod);
}



以上是关于CF 1528E的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1528E Mashtali and Hagh Trees

如何从后台弹出片段

cf 模拟

CF1435 游记

无法解析符号 c882c94be45fff9d16a1cf845fc16ec5

本人想学习破解技术但是看不懂反汇编代码!求助!!