• BZOJ 3782: 上学路线


    3782: 上学路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 211  Solved: 82
    [Submit][Status][Discuss]

    Description

    小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M)。小C家住在西南角,学校在东北角。现在有T个路口进行施工,小C不能通过这些路口。小C喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走;而小C又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条。由于答案可能很大,所以小C只需要让你求出路径数mod P的值。

    Input

    第一行,四个整数N、M、T、P。
    接下来的T行,每行两个整数,表示施工的路口的坐标。

    Output

    一行,一个整数,路径数mod P的值。
     
     

    Sample Input

    3 4 3 1019663265
    3 0
    1 1
    2 2

    Sample Output

    8

    HINT

    1<=N,M<=10^10

    0<=T<=200

    p=1000003或p=1019663265

    Source

     
    [Submit][Status][Discuss]

    Lucas定理 + 中国剩余定理CRT

      1 #include <cstdio>
      2 #include <algorithm>
      3 
      4 #define int long long
      5 
      6 const int mxt = 205;
      7 
      8 int n, m, t, p, f[mxt];
      9 
     10 struct point
     11 {
     12     int x, y;
     13 }pt[mxt];
     14 
     15 inline bool cmp(const point &a, const point &b)
     16 {
     17     if (a.x != b.x)
     18         return a.x < b.x;
     19     else
     20         return a.y < b.y;
     21 }
     22 
     23 namespace case1    // p = 1000003
     24 {
     25     const int siz = 1000005;
     26     
     27     int fac[siz], inv[siz];
     28     
     29     int lucas(int a, int b)
     30     {
     31         if (a < b)
     32             return 0;
     33         
     34         if (a < p && b < p)
     35             return fac[a] * inv[b] % p * inv[a - b] % p;
     36         
     37         return lucas(a / p, b / p) * lucas(a % p, b % p) % p;
     38     }
     39     
     40     inline void prework(void)
     41     {
     42         fac[0] = fac[1] = 1;
     43         inv[0] = inv[1] = 1;
     44         
     45         for (int i = 2; i <= p; ++i)
     46         {
     47             fac[i] = fac[i - 1] * i % p;
     48             inv[i] = inv[p % i] * (p - p/i) % p;
     49         }
     50         
     51         for (int i = 2; i <= p; ++i)
     52             inv[i] = inv[i] * inv[i - 1] % p;
     53     }
     54     
     55     inline int calc(int a, int b)
     56     {
     57         return lucas(a + b, a);
     58     }
     59     
     60     inline void main(void)
     61     {
     62         prework();
     63         
     64         int ans = calc(n, m);
     65         
     66         for (int i = 1; i <= t; ++i)
     67         {
     68             f[i] = calc(pt[i].x, pt[i].y);
     69             
     70             for (int j = 1; j < i; ++j)
     71                 if (pt[j].x <= pt[i].x && pt[j].y <= pt[i].y)
     72                     f[i] = (f[i] - f[j] * calc(pt[i].x - pt[j].x, pt[i].y - pt[j].y) % p + p) % p;
     73         }
     74         
     75         for (int i = 1; i <= t; ++i)
     76             if (pt[i].x <= n && pt[i].y <= m)
     77                 ans = (ans - f[i] * calc(n - pt[i].x, m - pt[i].y) % p + p) % p;
     78         
     79         printf("%lld
    ", ans);
     80     }
     81 }
     82 
     83 namespace case2    // p = 3 * 5 * 6793 * 10007
     84 {
     85     const int siz = 10010;
     86     
     87     const int mod[4] = 
     88     {
     89         3, 5, 6793, 10007
     90     };
     91     
     92     int fac[4][siz], inv[4][siz];
     93     
     94     inline void prework(void)
     95     {
     96         for (int i = 0; i < 4; ++i)
     97         {
     98             fac[i][0] = fac[i][1] = 1;
     99             inv[i][0] = inv[i][1] = 1;
    100             
    101             for (int j = 2; j <= mod[i]; ++j)
    102             {
    103                 fac[i][j] = fac[i][j - 1] * j % mod[i];
    104                 inv[i][j] = inv[i][mod[i] % j] * (mod[i] - mod[i]/j) % mod[i];
    105             }
    106             
    107             for (int j = 2; j <= mod[i]; ++j)
    108                 inv[i][j] = inv[i][j - 1] * inv[i][j] % mod[i];
    109         }
    110     }
    111     
    112     int lucas(int a, int b, int k)
    113     {
    114         if (a < b)
    115             return 0;
    116             
    117         if (a < mod[k] && b < mod[k])
    118             return fac[k][a] * inv[k][b] % mod[k] * inv[k][a - b] % mod[k];
    119         
    120         return lucas(a / mod[k], b / mod[k], k) * lucas(a % mod[k], b % mod[k], k) % mod[k];
    121     }
    122     
    123     inline int calc(int a, int b)
    124     {
    125         return (
    126             lucas(a + b, a, 0) * 339887755 % p
    127         +    lucas(a + b, a, 1) * 407865306 % p
    128         +    lucas(a + b, a, 2) * 673070820 % p
    129         +    lucas(a + b, a, 3) * 618502650 % p
    130         ) % p;
    131     }
    132     
    133     inline void main(void)
    134     {
    135         prework();
    136         
    137         int ans = calc(n, m);
    138         
    139         for (int i = 1; i <= t; ++i)
    140         {
    141             f[i] = calc(pt[i].x, pt[i].y);
    142             
    143             for (int j = 1; j < i; ++j)
    144                 if (pt[j].x <= pt[i].x && pt[j].y <= pt[i].y)
    145                     f[i] = (f[i] - f[j] * calc(pt[i].x - pt[j].x, pt[i].y - pt[j].y) % p + p) % p;
    146         }
    147         
    148         for (int i = 1; i <= t; ++i)
    149             if (pt[i].x <= n && pt[i].y <= m)
    150                 ans = (ans - f[i] * calc(n - pt[i].x, m - pt[i].y) % p + p) % p;
    151         
    152         printf("%lld
    ", ans);
    153     }
    154 }
    155 
    156 signed main(void)
    157 {
    158     scanf("%lld%lld%lld%lld", &n, &m, &t, &p);
    159     
    160     for (int i = 1; i <= t; ++i)
    161         scanf("%lld%lld", &pt[i].x, &pt[i].y);
    162     
    163     std::sort(pt + 1, pt + t + 1, cmp);
    164     
    165     if (p == 1000003)
    166         case1::main();
    167     else
    168         case2::main();
    169 }

    @Author: YouSiki

  • 相关阅读:
    Diango基础学习
    Python02-作业(购物车)
    使用spring boot + Thymeleaf实现web小页面
    Python-01作业(登录和三级菜单)
    Java反射机制
    Socket编程
    利用java的url实现小型的网页爬虫
    关于在spring boot里使用Thymeleaf模板的application.properties配置
    Spring
    Spring-bean的自动装配
  • 原文地址:https://www.cnblogs.com/yousiki/p/6438815.html
Copyright © 2020-2023  润新知