首页 > 其他分享 >AtCoder Beginner Contest 180 F Unbranched

AtCoder Beginner Contest 180 F Unbranched

时间:2023-10-16 14:14:27浏览次数:38  
标签:AtCoder typedef Unbranched ll long 180 maxn define mod

洛谷传送门

AtCoder 传送门

首先进行一个容斥,把连通块最大值 \(= K\) 变成 \(\le K\) 的方案数减去 \(\le K - 1\) 的方案数。

考虑 dp,设 \(f_{i, j}\) 表示当前用了 \(i\) 个点,\(j\) 条边。转移即枚举其中一个连通块的大小 \(k\)。为了不算重,我们强制让这个连通块包含点 \(1\),类比状压中枚举包含 \(\text{lowbit}(S)\) 的子集。

  • 如果这个连通块是环,那么给这个连通块标号 \(1 \sim k\) 的方案数为 \(\frac{(k - 1)!}{2}\),从 \(f_{i - k, j - k}\) 转移。特别地,\(2\) 元环的方案数为 \(1\)。
  • 如果这个连通块是链,那么方案数为 \(\frac{k!}{2}\),从 \(f_{i - k, j - (k - 1)}\) 转移。

还要乘一个给这 \(k\) 个点选择标号的方案数。\(1\) 被确定一定要选,剩下 \(i - 1\) 个标号要选 \(k - 1\) 个,所以方案数就是 \(\binom{i - 1}{k - 1}\)。

时间复杂度 \(O(n^3)\)。

code
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 310;
const ll mod = 1000000007;
const ll inv2 = (mod + 1) / 2;

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

ll n, m, K, fac[maxn], ifac[maxn];

inline ll C(ll n, ll m) {
	if (n < m || n < 0 || m < 0) {
		return 0;
	} else {
		return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
	}
}

ll f[maxn][maxn];

inline void upd(ll &x, ll y) {
	((x += y) >= mod) && (x -= mod);
}

inline ll calc(ll K) {
	if (!K) {
		return 0;
	}
	mems(f, 0);
	f[0][0] = 1;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j <= m; ++j) {
			f[i][j] = f[i - 1][j];
			for (int k = 2; k <= K && k <= i; ++k) {
				if (k <= j && k > 2) {
					upd(f[i][j], f[i - k][j - k] * C(i - 1, k - 1) % mod * fac[k - 1] % mod * inv2 % mod);
				}
				if (k <= j && k == 2) {
					upd(f[i][j], f[i - k][j - k] * C(i - 1, k - 1) % mod);
				}
				if (k - 1 <= j) {
					upd(f[i][j], f[i - k][j - (k - 1)] * C(i - 1, k - 1) % mod * fac[k] % mod * inv2 % mod);
				}
			}
		}
	}
	return f[n][m];
}

void solve() {
	scanf("%lld%lld%lld", &n, &m, &K);
	if (n < m || n < K) {
		puts("0");
		return;
	}
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) {
		fac[i] = fac[i - 1] * i % mod;
	}
	ifac[n] = qpow(fac[n], mod - 2);
	for (int i = n - 1; ~i; --i) {
		ifac[i] = ifac[i + 1] * (i + 1) % mod;
	}
	printf("%lld\n", (calc(K) - calc(K - 1) + mod) % mod);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,Unbranched,ll,long,180,maxn,define,mod
From: https://www.cnblogs.com/zltzlt-blog/p/17767198.html

相关文章

  • Programming abstractions in C阅读笔记:p179-p180
    《ProgrammingAbstractionsInC》学习第60天,p179-p180总结。一、技术总结1.palindrome(回文)(1)包含单个字符的字符串(如"a"),或者空字符串(如"")也是回文。(2)示例:“level”、"noon"。2.predicatefunction(1)predicate的意思pre-("forth")+*deik-("show"),“t......
  • AtCoder Beginner Contest 324
    D-SquarePermutation须知:最大的平方数的平方一定小于等于10n,平方数最多为10(n/2)(因为再大会越界)因为要求的数一定是原数的排列组合,所以它们的元素和对应的元素个数一定相同所以只要判断平方数的字符串是否与原字符串相等即可(这里可以利用排序判断)点击查看代码#include<bi......
  • AtCoder Beginner Contest 324 DF题题解
    比赛链接D-SquarePermutation其实比较简单,但是比赛时候脑子不转了,竟然在尝试枚举全排列,然后算了一下复杂度直接不会做了。正解应该是枚举完全平方数,底数枚举到\(sqrt(10^{14})\)即可,因为n最大为13。然后统计一下这个完全平方数各个数字出现了多少个,和读入的比较一下是......
  • Atcoder Beginner Contest 324 F Beautiful Path 题解-分数规划
    为了更好的阅读体验,请点击这里分数规划小技巧:尽可能将式子写成存在某种取值,使得不等式成立的形式。不然可能需要绕几个弯才能想出来。题目链接题目大意:给出一个DAG,每条边有一个\(b_i,c_i\),保证从编号小的边向编号大的边连边,且\(1\)到\(n\)必有路径,求\(1\)到\(n\)......
  • AtCoder Beginner Contest 321 C-321-like Searcher
    可以观察到0-9的所有子集都能恰组成一个满足题目条件的数字,所以共有1022个数{除空集和0}方法就是二元枚举,找出所有数然后排序。#include<iostream>#include<cstdio>#include<vector>#include<algorithm>usingnamespacestd;usingll=longlong;vector<ll>v;sig......
  • Atcoder beginner constest319 Minimum Width
    因为要求窗口的最小宽度,当宽度为w时满足条件,那么宽度为w+1时也满足条件,有此可见是有单调性的,那么可以用二分搜的方法,且此题目一定有解。因为M最大为2乘以10的5次方,Li最大为10的9次方,所以宽度最大为2乘以10的14次方,单词每次间隔1,所以这里设成10的17次方。之后就是套二分模板解暴力......
  • CF1801C 做题笔记
    题目链接一道需要挖掘一些性质的dpt,居然独立想出来了。本蒟蒻太菜了只会树状数组的做法,单调栈不会。先考虑只管对答案有贡献的音乐,这当然是正确的,因为我们可以把对答案没有贡献的音乐放到最后。对于每一首乐曲,我们也能对它进行一个简单的处理来模拟听的过程,维护一个值$lst$,......
  • AtCoder Regular Contest 166
    Preface上周末因为上课而且这天下午还有CF要打,所以就没现场打这场ARC了这两天事情也特别多导致写题的时间很少,摸了好久总算是补了四个题A-ReplaceCorSwapAB感觉是我做法复杂了,怎么A题码量好大首先我们找到所有\(Y\)中为\(C\)的位置,显然对应的\(X\)中的位置也必须为\(C......
  • 题解 AtCoder wtf22_day1_b【Non-Overlapping Swaps】
    题解AtCoderwtf22_day1_b【Non-OverlappingSwaps】problem给定一个排列,要求交换最多\(n-1\)对元素,使得这个排列变成[1,2,...,n]的有序排列。当然没有那么简单,对于交换还是有限制的,对于相邻的两次交换,不妨叫做\((l_i,r_i)\)和\((l_{i+1},r_{i+1})\),必须满足这两个交......
  • Atcoder Grand Contest 016 E - Poor Turkeys
    先思考这样一个问题:对于一只火鸡\(i\),我们应该如何判断它最后是否能活下来。如果我们正着判断,我们其实并没有足够的证据表明每一次操作我们应该保留哪只火鸡,也就没法判断最终的答案。但是如果我们倒着考虑,我们发现,如果最后一次操作的两个火鸡都不是\(i\),那么这次操作选啥对答案......