AtCoder ABC154 F

题目大意\(f(r,c)=C_{r+c}^r\),要求输出 \(\sum_{i=r_1}^{r_2}\sum_{j=c_1}^{c_2} f(i,j)\),其中 \(r_2,r_2,c_1,c_2\) 为给定值。

分析

\[g(r,c)=\sum_{i=0}^r\sum_{j=0}^c f(i,j) \]

则题目所求为

\[\sum_{i=r_1}^{r_2}\sum_{j=c_1}^{c_2} f(i,j)=g(r_2,c_2)-g(r_2,c_1-1)-g(r_1-1,c_2)+g(r_1-1,c_1-1) \]

如果我们能快速计算 \(g\) 则就解决了问题。

现在我们考虑如何用 \(f(r,\cdots)\) 求出 \(f(r+1,c)\),我们有

\[f(r+1,c)-f(r,c)=C_{r+1+c}^{r+1}-C_{r+c}^r=\frac{(r+c+1)!}{(r+1)!c!}-\frac{(r+c)!}{r!c!}=\frac{(r+c+1)!-(r+c)!(r+1)}{(r+1)!c!}=\frac{(r+c)![(r+c+1)-(r+1)]}{(r+1)!c!}=\frac{(r+c)!}{(r+1)!(c-1)!}=f(r+1,c-1) \]

也就是说,我们有递归式

\[f(r+1,c)=f(r,c)+f(r+1,c-1)=f(r,c)+f(r,c-1)+f(r+1,c-2)=\cdots=f(r,c)+f(r,c-1)+f(r,c-2)+\cdots+f(r,0)=\sum_{i=0}^cf(r,i) \]

那么

\[g(r,c)=\sum_{i=0}^r\sum_{j=0}^c f(i,j)=\sum_{i=0}^rf(i+1,c)=\sum_{i=0}^rf(c,i+1)=f(c+1,r+1)-1 \]

那么代码就很简单了。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod = 1e+9 + 7;

ll r1, r2, c1, c2;

ll qPow(ll a, ll b)
{
	a %= mod;
	
	ll res = 1;
	while(b) {
		if(b & 1) res = res * a % mod;
		a = a * a % mod, b >>= 1;
	}
	return res;
}

ll C(ll n, ll m)
{
	if(n < m) return 0;
	
	ll res = 1;
	for(int i = 1; i <= m; ++i)
		res = res * (n - i + 1) % mod * qPow(i, mod - 2) % mod;
	return res;
}

int main()
{
	scanf("%lld%lld%lld%lld", &r1, &c1, &r2, &c2);
	
	++r2, ++c2;
	printf("%lld", ((C(r2 + c2, c2) - C(r1 + c2, c2) - C(r2 + c1, c1) + C(r1 + c1, c1)) % mod + mod) % mod);
}
posted @ 2020-02-13 02:00  whx1003  阅读(375)  评论(0编辑  收藏  举报