Logo FiraCode 的博客

博客

CF1288C题解

...
FiraCode
2025-12-01 12:55:17
什么意思呢

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2021-11-29 12:04:10

题解思路:

$2m$ 个数字

{

1 -- 1

2 -- 2

排序

a : 1 1 , b : 2 2 

a = [1 , 1] , b = [2 , 2]

}

对于一种合法的数组而言,每个数组出现的次数构成一个大小n的数组 = $[1 , 2]$

1 2 2 2

1 -- 1

2 -- 3

一个 $ab$ 对唯一对应一个数字出现的次数。

可以把题目转化成 :求 $1-n$ 之间的出现次数。

假设 $n = 4$ ,$m = 5$ :

1 -- ? 举例填 3

2 -- ? 举例填 1

3 -- ? 举例填 2

4 -- ? 举例填 4

1 1 1 2 3 3 ………… $a = []$ , $b = []$

数组 1 1 1 2 3 3 4 4 4 4 。

$a = [1 1 1 2 3]$ $b = [3 4 4 4 4]$

$3 + 1 + 2 + 4$ 必须 $= 2m$。

即对应的数加起来必须是 $2m$。

即求$a + b + c + d = 2m$。

$(a , b , c , d)$ 有多少种。

就变成了组合数学中的划分,模板。

结果:$c[n + 2m - 1][n - 1]$。

当然别忘了取模

(调了半个小时,突然发现 $ans = 0$)

代码:

#include <bits\/stdc++.h>\/\/万能头文件 
using namespace std;
#define ll int
#define mod 1000000007
int n , m;
inline ll read() {\/\/快读模板 
	register ll num = 0 , neg = 1;
	register char ch = getchar();
	while (ch < '0' && ch > '9'){
		if (ch == '-')neg = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		num = (num << 1) + (num << 3) + (ch ^ 48);
		ch = getchar();
	}
	return num * neg;
}
inline void print(int num) {\/\/快输模板 
	if (num < 0)putchar('-') , num = -num;
	if (num > 9)print(num \/ 10);
	putchar(num % 10 + '0');
}
long long kuaipow(long long a , long long b , long long m) {\/\/快速幂加取模 
	long long ans = 1;
	while (b > 0) {
		if (b & 1)ans = ans * a % m;
		a = a * a % m;
		b >>= 1; 
	}
	return ans; 
}
long long inv(long long a) {
	return kuaipow(a , mod - 2 , mod);\/\/调用函数
} 
int main() {
	n = read() , m = read();\/\/读入
	long long ans = 1;\/\/储存最终答案
	for (int i = 1; i <= n - 1; ++ i)\/\/计算组合数学 
		ans = ans * inv(i) % mod;\/\/要取模!!! 
	for (int i = 1; i <= 2 * m; ++ i)\/\/计算组合数学 
		ans = ans * inv(i) % mod;
	for (int i = 1; i <= n + 2 * m - 1; ++ i)\/\/计算组合数学 
		ans = ans * i % mod;
	print(ans) , putchar('\n');\/\/输出答案 
	return 0;
}

如果有错误请奆佬指出

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。