AT5295 [ABC154F] Many Many Paths
- 题意:斯努克站在一个二维平面上。在一次操作中,他可以向 xx 轴正方向或是 yy 轴正方向移动一步。定义函数 f(r,c)f(r,c) 为通过上述操作,斯努克从 (0,0)(0,0) 走到 (r,c)(r,c) 的方案总数。现在给定 r1,r2,c1r1,r2,c1 和 c2c2,请你求出所有 f(i,j)f(i,j) 之和,其中 r1≤i≤r2r1≤i≤r2 且 c1≤j≤c2c1≤j≤c2。形式化的,请你求出r2∑i=r1c2∑j=c1f(i,j)r2∑i=r1c2∑j=c1f(i,j) 的值。由于结果可能很大,请将结果对 109+7109+7 取模。
- 题解:首先,从 0,00,0 到 i,ji,j 的距离是 C(i+j,i)C(i+j,i) 意义代表是必须走 i+ji+j 步,然后必须走 ii 步横着的或者 C(i+j,j)C(i+j,j) 或者走 jj 步竖着的。然后开始愉快推柿子了,即 Cm+1n+m+1=n∑i=0Cmm+iCm+1n+m+1=n∑i=0Cmm+i 原柿子是这样的
r2∑i=r1c2∑j=c1Cii+jr2∑i=r1c2∑j=c1Cii+j
r2∑i=r1(Ci+1i+c2+1−Ci+1i+c1+1−1)r2∑i=r1(Ci+1i+c2+1−Ci+1i+c1+1−1)
化成了一维。然后就是逆元预处理的话会快一倍。
- 代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const ll NN = 1e7 + 99;
const ll N = 2e6 + 99;
const ll mod = 1e9 + 7;
const ll maxn = 1e7;
ll fac[N];
ll inv_fac[N];
ll q_pow(ll a, ll k) {
ll ret = 1;
ll x = a;
while (k) {
if (k & 1) (ret *= x) %= mod;
k >>= 1;
(x *= x) %= mod;
}
return ret;
}
ll inv(ll a) { return (q_pow(a, mod - 2) % mod + mod) % mod; }
void init() {
fac[0] = 1;
inv_fac[0] = 1;
fac[1] = 1;
for (ll i = 1; i < N; i++) {
fac[i] = fac[i - 1] * i % mod;
inv_fac[i] = inv(fac[i]);
}
}
ll C(ll n, ll m) { return fac[n] * inv_fac[m] % mod * inv_fac[n - m] % mod; }
void solve() {
ll sum = 0;
ll c1, c2, r1, r2;
cin >> r1 >> c1 >> r2 >> c2;
for (int i = r1; i <= r2; i++) {
sum = (sum +
((C(i + 1 + c2, i + 1) - C(i + c1, i + 1)) % mod + mod) % mod) %
mod;
}
cout << sum % mod << endl;
}
signed main() {
ios::sync_with_stdio(0);
init();
ll t = 1;
while (t--) solve();
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步