zoukankan      html  css  js  c++  java
  • AT5295 [ABC154F] Many Many Paths

    原题链接

    • 题意:斯努克站在一个二维平面上。在一次操作中,他可以向 (x) 轴正方向或是 (y) 轴正方向移动一步。定义函数 (f(r,c)) 为通过上述操作,斯努克从 ((0,0)) 走到 ((r,c)) 的方案总数。现在给定 (r_1,r_2,c_1)(c_2),请你求出所有 (f(i,j)) 之和,其中 (r_1 le i le r_2)(c_1 le j le c_2)。形式化的,请你求出(sumlimits_{i=r_1}^{r_2}sumlimits_{j=c_1}^{c_2}f(i,j)) 的值。由于结果可能很大,请将结果对 (10^9+7) 取模。
    • 题解:首先,从 (0, 0)(i, j) 的距离是 (C(i + j, i)) 意义代表是必须走 (i + j) 步,然后必须走 (i) 步横着的或者 (C(i + j, j)) 或者走 (j) 步竖着的。然后开始愉快推柿子了,即 (C^{m + 1}_{n + m + 1} = sumlimits_{i=0}^{n} C^{m }_{m + i}) 原柿子是这样的

    [sumlimits_{i=r_1}^{r_2}sumlimits_{j=c_1}^{c_2} C^{i}_{i+j} ]

    [sumlimits_{i=r_1}^{r_2} (C^{i + 1}_{i+c2 + 1} - C^{i + 1}_{i+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;
    }
    
  • 相关阅读:
    拉格朗日插值
    [数论] hdu 5974 A Simple Math Problem (数论gcd)
    混合图欧拉回路
    上下界网络流
    HDU 6623 Minimal Power of Prime(数学)
    图的连通度
    最小点权覆盖和最大点权独立集
    最大权闭合子图(最小割,蕴含式最大获利问题)
    CodeForces Goodbye 2017
    网络流建模汇总
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14603314.html
Copyright © 2011-2022 走看看