1101 不定方程的解

// 1101.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
* 不定方程的解
http://oj.daimayuan.top/course/22/problem/1179

给出不定方程 ∑ni=1xi=m和 n个限制条件 xi≤bi,其中 m,bi∈N
求方程的非负整数解的个数。
由于答案很大,输出对109+7取模的结果。

输入格式
第一行两个整数n,m(1≤n≤10,1≤m≤109),接下来一行n个整数b1,b2,…,bn(1≤bi≤m)。

输出格式
一个数,表示答案。

样例输入
3 5
2 3 4
样例输出
11
*/

#include <iostream>

using namespace std;

long long n, m;
const long long P = 1e9 + 7;
long long ans = 0;
long long B[20];


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


long long C(long long a, long long b, long long p) {
	if (b > a) return 0;
	long long ret = 1;
	for (long long i = 1, j = a; i <= b; i++, j--) {
		ret = ret * j % p;
		ret = ret * qmi(i, p - 2, p) % p;
	}

	return ret;
}


long long lucas(long long a, long long b, long long p) {
	if (a < p && b < p) return C(a, b, p);
	return C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}



void dfs(int idx, int cnt, long long sum) {
	if (idx == n) {
		long long total = lucas(m + n - 1 - sum, n - 1, P);
		if (cnt % 2 != 0) {
			total = -total;
		}
		
		ans += total;
		ans %= P;

		return;
	}

	dfs(idx + 1, cnt, sum);

	cnt++, sum += B[idx]+1;
	dfs(idx + 1, cnt, sum);
	cnt--, sum -= B[idx]+1;

	return;
}

void solve() {
	dfs(0, 0, 0);
	if (ans < 0) ans = (ans + P) % P;
	cout << ans << endl;
}



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

	solve();


	return 0;
}
#include <iostream>


using namespace std;

typedef long long ll;
const ll mod = 1e9 + 7;
ll b[20];
int n, m;
ll ans;
ll ifac, inv[20];

ll calc(int x) {
	ll ans = 1;
	for (int i = 1; i <= n - 1; i++)
		ans = ans * (x + i) % mod;
	ans = ans * ifac % mod;
	return ans;
}

void dfs(int d, int sgn, ll sum) {
	if (d == n) {
		if (sum > m) return;
		ans += sgn * calc(m - sum);
		ans %= mod;
	}
	else {
		dfs(d + 1, sgn, sum);
		dfs(d + 1, -sgn, sum + b[d]+1);
	}
}


int main() {
	cin >> n >> m;
	ifac = 1;
	//代码源 数论课查看 逆元
	for (int i = 1; i < n; i++) {
		if (i == 1) inv[i] = 1;
		else inv[i] = (mod - mod / i) * inv[mod % i] % mod;
		ifac = ifac * inv[i] % mod;
	}

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

	//i个变量 容斥系数 数值之和
	dfs(0, 1, 0);
	ans = (ans+mod) % mod;
	cout << ans << endl;
	return 0;
}

posted on   itdef  阅读(20)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2019-12-16 acwing 850. Dijkstra求最短路 II 模板
2019-12-16 acwing 849 Dijkstra求最短路 I 模板

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示