214. Devu和鲜花

// 214. Devu和鲜花.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*

https://www.acwing.com/problem/content/216/
Devu 有 N 个盒子,第 i 个盒子中有 Ai 枝花。

同一个盒子内的花颜色相同,不同盒子内的花颜色不同。

Devu 要从这些盒子中选出 M 枝花组成一束,求共有多少种方案。

若两束花每种颜色的花的数量都相同,则认为这两束花是相同的方案。

结果需对 109+7 取模之后方可输出。

输入格式
第一行包含两个整数 N 和 M。

第二行包含 N 个空格隔开的整数,表示 A1,A2,…,AN。

输出格式
输出一个整数,表示方案数量对 109+7 取模后的结果。

数据范围
1≤N≤20,
0≤M≤1014,
0≤Ai≤1012
输入样例:
3 5
1 3 2
输出样例:
3



5 10
3 1 12 3 15

20 10000000000000
300519958870 832281042067 319299805729 757240907384 627775401292 247728933123 11195305815 751824230536 719180823394 591150126216 162654015097 186816647538 598133282514 196929671451 623339301954 967995745587 960509226608 997388605799 312397159266 699519518567


*/

#include <iostream>

using namespace std;

typedef long long LL;

const int N = 25;
const int MOD = 1e9 + 7;
LL a[N];
LL n, m;
LL total;

LL qmi(LL a, LL b) {
	LL res = 1;
	while (b) {
		if (b & 1) res = res * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	return res;
}


LL C(LL a, LL b) {
	if (b > a) return 0;
	a = a % MOD;
	LL up = 1;
	for (LL i = 0; i < b; i++) {
		up *= a - i; up %= MOD;
	}
	LL down = 1;
	for (LL i = 1; i <= b; i++) { down *= i; down %= MOD; }

	down = qmi(down, MOD - 2) % MOD;
	return up * down % MOD;
}


void dfs(int idx,LL curr,int cnt) {
	if (idx == n) {
		int flag = 1;
		if (cnt % 2 !=0) {
			flag *= -1;
		}
		total = total + flag * C( curr, n- 1) % MOD;
		total %= MOD;
		return;
	}

	curr -= a[idx]+1; cnt++;
	dfs(idx + 1, curr, cnt);
	curr += a[idx]+1; cnt--;

	dfs(idx + 1, curr, cnt);
}


int main()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	dfs(0,m+n-1,0);

	cout << (total + MOD) % MOD;

	return 0;
}

posted on 2025-04-07 11:49  itdef  阅读(8)  评论(0)    收藏  举报

导航