题目描述

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

输入

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

输出

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

样例输入

3 4 3 1019663265
3 0
1 1
2 2

样例输出

8

提示

p=1000003 或 p=1019663265


题解

dp+Lucas定理+中国剩余定理

设$f[i]$表示从$(0,0)$走到第i个坏点(终点算作第T+1个坏点),中途不经过其它坏点的方案数。

那么直接求$f[i]$比较困难,考虑单步容斥,用总方案数-经过坏点的方案数推出$f[i]$。

从$(0,0)$走到$(n,m)$的总方案数为$C_{n+m}^n$,可以看做总共n+m步,其中n步是x方向。

而经过坏点的方案数,枚举其经过的第一个坏点,那么它的贡献为|从$(0,0)$走到该点,中途不经过其它坏点的方案数|*|从这个坏点走到当前点的方案数|。

第一个即为坏点的$f$值,第二个用组合数求法求出。

最后的答案就是$f[T+1]$。

然而本题较为恶心之处在于模数,当p=1000003时可以直接使用Lucas定理,而当p=1019663265时p不为质数,将其分解质因数为3*5*6793*10007,使用Lucas定理分别求出组合数在模这些质因子意义下的值,再使用中国剩余定理CRT合并,才能得到组合数模1019663265的值。

细节还是有点多,代码已经差不多优化到极限了,凑合着看吧。。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod[] = {1000003 , 3 , 5 , 6793 , 10007} , temp = 1019663265;
struct data
{
ll x , y;
bool operator<(const data a)const {return x == a.x ? y < a.y : x < a.x;}
}a[210];
ll f[210] , fac[5][1000010] , d[5];
bool flag;
ll pow(ll x , ll y , ll p)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % p;
x = x * x % p , y >>= 1;
}
return ans;
}
ll choose(ll n , ll m , ll p)
{
if(n < m) return 0;
if(n < mod[p] && m < mod[p]) return fac[p][n] * pow(fac[p][m] , mod[p] - 2 , mod[p]) % mod[p] * pow(fac[p][n - m] , mod[p] - 2 , mod[p]) % mod[p];
return choose(n / mod[p] , m / mod[p] , p) * choose(n % mod[p] , m % mod[p] , p) % mod[p];
}
ll C(ll n , ll m)
{
if(!flag) return choose(n , m , 0);
int i;
ll ans = 0;
for(i = 1 ; i < 5 ; i ++ ) d[i] = choose(n , m , i);
for(i = 1 ; i < 5 ; i ++ ) ans = (ans + temp / mod[i] * pow(temp / mod[i] , mod[i] - 2 , mod[i]) % temp * d[i] % temp) % temp;
return ans;
}
int main()
{
ll n , m;
int p , T , i , j;
scanf("%lld%lld%d%d" , &n , &m , &T , &p) , flag = (p != 1000003);
for(i = 0 ; i < 5 ; i ++ )
for(fac[i][0] = j = 1 ; j < mod[i] ; j ++ )
fac[i][j] = fac[i][j - 1] * j % mod[i];
for(i = 1 ; i <= T ; i ++ ) scanf("%lld%lld" , &a[i].x , &a[i].y);
a[++T].x = n , a[T].y = m;
sort(a + 1 , a + T + 1);
for(i = 1 ; i <= T ; i ++ )
{
f[i] = C(a[i].x + a[i].y , a[i].x);
for(j = 1 ; j < i ; j ++ )
if(a[j].y <= a[i].y)
f[i] = (f[i] - f[j] * C(a[i].y - a[j].y + a[i].x - a[j].x , a[i].y - a[j].y) % p + p) % p;
}
printf("%lld\n" , f[T]);
return 0;
}

【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理的更多相关文章

  1. 卢卡斯定理&&中国剩余定理

    卢卡斯定理(模数较小,且是质数) 式子C(m,n)=C(m/p,n/p)*C(m%p,n%p)%p 至于证明(我也不会QAQ,只要记住公式也该就好了). 同时卢卡斯定理一般用于组合数取模上 1.首先当 ...

  2. BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理

    我们枚举第一个经过的坏点,然后DP即可. 状态转移方程不是难点,难点在于组合数的处理. 将狼踩尽的博客中有很详细的证明过程,但是我只记住了结论 $n=a_1 * p^k+a_2*p^k-1...$ $ ...

  3. 【bzoj1951】[Sdoi2010]古代猪文 费马小定理+Lucas定理+中国剩余定理

    题目描述 求  $g^{\sum\limits_{k|n}C_{n}^{\frac nk}}\mod 999911659$ 输入 有且仅有一行:两个数N.G,用一个空格分开. 输出 有且仅有一行:一个 ...

  4. Ceizenpok’s formula Gym - 100633J 扩展Lucas定理 + 中国剩余定理

    http://codeforces.com/gym/100633/problem/J 其实这个解法不难学的,不需要太多的数学.但是证明的话,我可能给不了严格的证明.可以看看这篇文章 http://ww ...

  5. hdu 5446 Unknown Treasure Lucas定理+中国剩余定理

    Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  6. 【题解】P2480 [SDOI2010]古代猪文 - 卢卡斯定理 - 中国剩余定理

    P2480 [SDOI2010]古代猪文 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 猪王国的文明源远流长,博大精 ...

  7. Codeforces Round #460 (Div. 2).E 费马小定理+中国剩余定理

    E. Congruence Equation time limit per test 3 seconds memory limit per test 256 megabytes input stand ...

  8. 洛谷P2480 [SDOI2010]古代猪文(费马小定理,卢卡斯定理,中国剩余定理,线性筛)

    洛谷题目传送门 蒟蒻惊叹于一道小小的数论题竟能涉及这么多知识点!不过,掌握了这些知识点,拿下这道题也并非难事. 题意一行就能写下来: 给定\(N,G\),求\(G^{\sum \limits _{d| ...

  9. RSA遇上中国剩余定理

    1.Introduction 最近读论文刚好用到了这个,之前只是有耳闻,没有仔细研究过,这里就好好捋一下,会逐步完善 不过貌似CRT(中国剩余定理)的实现更容易被攻击 2. RSA: Overview ...

随机推荐

  1. BZOJ 1806: [Ioi2007]Miners 矿工配餐

    ime Limit: 10 Sec  Memory Limit: 64 MBSubmit: 910  Solved: 559[Submit][Status][Discuss] Description ...

  2. python3.6 配置COCO API出错解决方案

    使用Anaconda Prompt进行安装 问题出现的背景:在尝试使用mask-rcnn时,遇到了这个问题,最终解决掉了

  3. Spring 和 Mybatis 整合

    Spring 和 Mybatis 整合 Spring本身的Config文件: 在IDEA下面配置好文件后, 在WEB-INF下面有三个配置文件分别是web.xml, applicationContex ...

  4. 使用MaskedTextBox控件实现输入验证

    实现效果: 知识运用: MaskedTextBox控件的 Mask属性 BeepOnError属性 MaskInputRejected事件 实现代码: private void Form1_Load( ...

  5. WINDOWS-基础:SafeArray的使用方法

    1 SafeArray的作用 使用SafeArray SafeArray是VB中的数组存储方式.通过SafeArray,可以在VC++和VB间相互调用. SafeArray也是Automation中的 ...

  6. java 自定义一个容器类

    public class ArrayList { public int index = 0; Object[] objects = new Object[2]; public void add(Obj ...

  7. javaweb基础(13)_session防止表单重复提交

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...

  8. 【线性基】bzoj2322: [BeiJing2011]梦想封印

    线性基的思维题+图常见套路 Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantasy Seal)的特技,需要引 ...

  9. k8s的资源限制及资源请求

    容器的资源需求及限制:  需求:requests   ##定义容器运行时至少需要资源  限制:limits     ##定义容器运行时最多能分配的资源    requests:pod.spec.con ...

  10. Struts2和SpringMVC简单配置以及区别总结

    Struts2: struts 2 是一个基于MVC(mode-view-con)设计模式的Web应用框架,是由Struts1和WebWork两个经典框架发展而来的. 工作流程: 1客户端浏览器发出H ...