【HDU 6482】组合计数问题

1.题目链接。题目大意:一个人从(0,y1)走到(x1,0),另一个人从(0,y2)走到(x2,0).求他们路线不相交的方案数。

2.。。。行吧,这个题推了快1h,因为智商底。。其实很好理解,首先,我们不考虑任何限制,从(0,y)走到(x,0)的方案数其实就是一个组合数C(x+y,x).然后在不考虑任何限制的时候:ans=C(x1+y1,x1)*C(x2+y2,x2).如果二者相交,那么只需要保持y不变,x互换,然后就是C(x1+y2,x1)*C(x2+y1,x2).二者之差就是答案。这当然是聚聚们的写法了,如果正常的想法是,我们枚举所有的交点。然后减去,其实最后发现求和之后就是上边的第二种情况,但是这个求和十分的复杂。。。。。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+100;
const int mod = 1e9 + 7;
ll fac[maxn];
ll inv[maxn];
#pragma warning(disable:4996)
ll qpow(ll a, ll b, ll mod)
{
	ll res = 1;
	while (b)
	{
		if (b & 1)
			res = res * a%mod;
		a = a * a%mod;
		b >>= 1;
	}
	return res;
}
void inv_ini()
{
	fac[0] = 1;
	for (int i = 1; i < maxn; i++)
	{
		fac[i] = fac[i - 1] * i%mod;
	}
	inv[maxn - 1] = qpow(fac[maxn - 1], mod - 2, mod);
	for (int i = maxn - 2; i >= 0; i--)
	{
		inv[i] = inv[i + 1] * (i + 1) % mod;
	}
}
ll C(ll n, ll m)
{
	ll ans = fac[n] * inv[m] % mod*inv[n - m] % mod;
	return ans;
}
int main()
{
	int T;
	cin >> T;
	inv_ini();
	while (T--)
	{
		ll x1, x2, y1, y2;
		scanf("%lld%lld%lld%lld", &x1, &x2, &y1, &y2);
		ll ans = (C(x1 + y1, x1)*C(x2 + y2, x2)%mod - C(x1 + y2, x1)*C(x2 + y1, x2)%mod + mod) % mod;
		printf("%lld\n", ans);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_41863129/article/details/89739489
今日推荐