zoukankan      html  css  js  c++  java
  • AtCoder ABC 154F Many Many Paths

    题目链接:https://atcoder.jp/contests/abc154/tasks/abc154_f

    题目大意

      设$(r, c)$为二维坐标轴上的整数点,且r, c均为自然数。

      定义$f(r, c)$为从$(0, 0)$到$(r, c)$的所有路径总数(只能向上或向右走)。

      现给定两个点$(r1, c1)$和$(r2, c2)$$(r1 leq r2, c1 leq c2)$,求$displaystyle sum_{i=r1}^{r2} sum_{j=c1}^{c2} f(i, j)$, 并对$10^9 + 7$取模。

    分析

      不难看出,$f(r, c) = inom{r + c}{r}$。
      而$displaystyle sum_{j=c1}^{c2} f(r, j) = displaystyle sum_{j=c1}^{c2} inom{r + j}{r} =  displaystyle sum_{j=0}^{c2} inom{r + j}{r} -  displaystyle sum_{j=0}^{c1 - 1} inom{r + j}{r}$。
      利用朱世杰恒等式,可得$displaystyle sum_{j=c1}^{c2} f(r, j) = inom{r + c2 + 1}{r + 1} - inom{r + c1}{r + 1}$。

    代码如下

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 /*-------------------Define Start-------------------*/
      5 typedef bool BL;                        // 布尔类型
      6 typedef char SB;                        // 有符号1字节,8位
      7 typedef unsigned char UB;                // 无符号1字节,8位
      8 typedef short SW;                        // 有符号短整型,16位
      9 typedef unsigned short UW;                // 无符号短整型,16位
     10 typedef long SDW;                        // 有符号整型,32位
     11 typedef unsigned long UDW;               // 无符号整型,32位
     12 typedef long long SLL;                    // 有符号长整型,64位
     13 typedef unsigned long long ULL;            // 无符号长整型,64位
     14 typedef char CH;                        // 单个字符
     15 typedef float R32;                        // 单精度浮点数
     16 typedef double R64;                        // 双精度浮点数
     17 
     18 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
     19 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
     20 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
     21 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     22 #define ms0(a) memset(a,0,sizeof(a))
     23 #define msI(a) memset(a,0x7f,sizeof(a))
     24 #define LOWBIT(x) ((x)&(-x))
     25 
     26 #define MP make_pair
     27 #define PB push_back
     28 #define ft first
     29 #define sd second
     30 
     31 #define pr(x) cout << #x << " = " << x << "  "
     32 #define prln(x) cout << #x << " = " << x << endl
     33 
     34 const ULL mod = 1e9 + 7;                //常用模数(可根据题目需要修改)
     35 const ULL inf = 0x7fffffff;                //用来表示无限大
     36 const ULL infLL = 0x7fffffffffffffffLL;    //用来表示无限大
     37 /*-------------------Define End-------------------*/
     38 
     39 const UDW maxN = 1e6 + 7;
     40 SLL r1, c1, r2, c2;
     41 SLL ans;
     42 
     43 SLL fac[maxN * 2];
     44 void init_fact() {
     45     fac[0] = 1;
     46     For(i, 1, 2 * maxN - 1) {
     47         fac[i] = (i * fac[i - 1]) % mod;
     48     }
     49 }
     50 
     51 void input(){
     52     cin >> r1 >> c1 >> r2 >> c2;
     53     init_fact();
     54 }
     55 
     56 //ax + by = gcd(a, b) = d
     57 // 扩展欧几里德算法
     58 /**
     59  *    a*x + b*y = 1
     60  *    如果ab互质,有解
     61  *    x就是a关于b的逆元
     62  *    y就是b关于a的逆元
     63  *     
     64  *    证明: 
     65  *        a*x % b + b*y % b = 1 % b
     66  *        a*x % b = 1 % b
     67  *        a*x = 1 (mod b)
     68  */
     69 inline void ex_gcd(SLL a, SLL b, SLL &x, SLL &y, SLL &d){
     70     if(!b) {
     71         d = a, x = 1, y = 0;
     72     }
     73     else{
     74         ex_gcd(b, a % b, y, x, d);
     75         y -= x * (a / b);
     76     }
     77 }
     78 
     79 // 求a关于p的逆元,如果不存在,返回-1 
     80 // a与p互质,逆元才存在 
     81 inline SLL inv_mod(SLL a, SLL p = mod){
     82     SLL d, x, y;
     83     ex_gcd(a, p, x, y, d);
     84     return d == 1 ? (x % p + p) % p : -1;
     85 }
     86 
     87 inline SLL comb_mod(SLL m, SLL n) {
     88     SLL ret;
     89 
     90     if(m > n) {
     91         swap(m, n);
     92     } 
     93     
     94     ret = (fac[n] * inv_mod(fac[m], mod)) % mod;
     95     ret = (ret * inv_mod(fac[n - m], mod)) % mod;
     96     
     97     return ret;
     98 }
     99 
    100 void solve(){
    101     For(i, r1, r2) {
    102         ans = (ans + comb_mod(i + 1, c2 + i + 1) - comb_mod(i + 1, c1 + i) + mod) % mod;
    103     }
    104 }
    105 
    106 void output(){
    107     cout << ans << endl;
    108 }
    109 
    110 int main() {
    111     input();
    112     solve();
    113     output();
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    V8 下的垃圾回收机制
    数据库索引原理
    多线程的实现方法
    网元的概念
    Oracle 数据库实现数据合并:merge
    Linux账号管理
    Linux 进程管理 ps、top、pstree命令
    linux OS与SQL修改时区,系统时间
    数据库的几种模式
    linux上限值网速、限值带宽
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/12298366.html
Copyright © 2011-2022 走看看