传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3782

有部分分的传送门:https://www.luogu.org/problemnew/show/P4478

看到标题开始还以为是AHOI的小雪和小可可……

题解:乍一看会40pts:测试点1、2:n,m<=1000的直接O(nm)DP;测试点3、4:没有障碍物直接C(n+m,n),然后p=1e6+3是质数可以直接取模。

想了几分钟会60pts:测试点5、6:模数可以拆成几个不超过1e5的质数的乘积,直接算出C(n+m,n)对每个质数的模数,然后CRT合并一下就行了。

不会CRT的左转,我原来也是看这个博客学的:https://blog.csdn.net/niiick/article/details/80229217

其实满分也很可做,容斥一下就行了:把障碍物按x从小到大,x相同按y从小到大排序,然后f[i]表示不经过前(i-1)个障碍物但经过第i个障碍物的方案,然后增加最后一个点为(n,m),然后可以计算f[i]=C(x[i]+y[i],y[i])+Σf[j]C(x[i]-x[j]+y[i]-y[j],x[i]-x[j]),其中j满足x[j]<=x[i]&&y[j]<=y[i],这个计算由于T<=200算组合数+CRT合并也不会超时,复杂度O(T^2log)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+;
struct node{ll x,y;}a[N];
ll n,m,P,f[N],p[],fac[][N],inv[][N],mul[],imul[],g[];
int num,tp;
bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
ll qpow(ll a,ll b,ll p)
{
ll ret=;
while(b)
{
if(b&)ret=ret*a%p;
a=a*a%p,b>>=;
}
return ret;
}
ll c(ll a,ll b,int i)
{
if(a<b)return ;
if(a<p[i]&&b<p[i])return fac[i][a]*inv[i][b]%p[i]*inv[i][a-b]%p[i];
return c(a%p[i],b%p[i],i)*c(a/p[i],b/p[i],i)%p[i];
}
ll C(ll a,ll b)
{
if(!tp)return c(a,b,);
ll ret=;
for(int i=;i<=;i++)g[i]=c(a,b,i);
for(int i=;i<=;i++)ret=(ret+g[i]*mul[i]%P*imul[i]%P)%P;
return ret;
}
int main()
{
scanf("%lld%lld%d%lld",&n,&m,&num,&P);
for(int i=;i<=num;i++)scanf("%lld%lld",&a[i].x,&a[i].y);
a[++num]=(node){n,m};
sort(a+,a+num+,cmp);
if(P==1e6+)p[]=1e6+;else p[]=,p[]=,p[]=,p[]=,tp=;
if(tp)
{
for(int i=;i<=;i++)
{
mul[i]=P/p[i],imul[i]=qpow(mul[i],p[i]-,p[i]);
fac[i][]=;for(int j=;j<p[i];j++)fac[i][j]=fac[i][j-]*j%p[i];
inv[i][p[i]-]=qpow(fac[i][p[i]-],p[i]-,p[i]);
for(int j=p[i]-;j;j--)inv[i][j-]=inv[i][j]*j%p[i];
}
}
else{
fac[][]=;for(int i=;i<P;i++)fac[][i]=fac[][i-]*i%P;
inv[][P-]=qpow(fac[][P-],P-,P);
for(int i=P-;i;i--)inv[][i-]=inv[][i]*i%P;
}
for(int i=;i<=num;i++)
{
f[i]=C(a[i].x+a[i].y,a[i].x);
for(int j=;j<i;j++)if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
f[i]=(f[i]-f[j]*C(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)%P+P)%P;
}
printf("%lld",f[num]);
}

bzoj3782上学路线(Lucas+CRT+容斥DP+组合计数)的更多相关文章

  1. BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp

    其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:$A[i]\equiv B[i](mod$ $P[i])$. 对于这个东西,你可以这么思考:如果最后能求出一个解,那么这个解的增量一定 ...

  2. 【BZOJ4005】[JLOI2015] 骗我呢(容斥,组合计数)

    [BZOJ4005][JLOI2015] 骗我呢(容斥,组合计数) 题面 BZOJ 洛谷 题解 lalaxu #include<iostream> using namespace std; ...

  3. bzoj 3782 上学路线 卢卡斯定理 容斥 中国剩余定理 dp

    LINK:上学路线 从(0,0)走到(n,m)每次只能向上或者向右走 有K个点不能走求方案数,对P取模. \(1\leq N,M\leq 10^10 0\leq T\leq 200\) p=10000 ...

  4. CF1043F Make It One 容斥+dp+组合

    考试的时候考的一道题,感觉挺神的. 我们发现将所有数去重后最多只会选不到 $7$ 后 $gcd$ 就会变成 $1$. 令 $f[i][k]$ 表示选 $i$ 个数后 $gcd$ 为 $k$ 的方案数. ...

  5. 2017多校第8场 HDU 6143 Killer Names 容斥,组合计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6143 题意:m种颜色需要为两段长度为n的格子染色,且这两段之间不能出现相同的颜色,问总共有多少种情况. ...

  6. HDU 5794 A Simple Chess (容斥+DP+Lucas)

    A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...

  7. [CF1086E]Beautiful Matrix(容斥+DP+树状数组)

    给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...

  8. 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)

    题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...

  9. 【BZOJ3622】已经没有什么好害怕的了 容斥+DP

    [BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...

随机推荐

  1. java中的a++与++a的区别

    ++a:如果++在前就会先把a+1. a++:如果++在后就会先a然后在执行++的操作.代码: int a = 1; System.out.pritln(++a); //输出2 int s = 1; ...

  2. DAY04、流程控制if、while、for

    一.if 判断 语法一: if 条件: # 以下是上一条if 的子代码块 print(子代码1) print(子代码2) print(子代码3) 示例: # 路边飘过一个生物,要不要表白? sex = ...

  3. python数学第九天【统计】

  4. PHP爬虫框架Snoopy的使用

    参考文档: http://ibillxia.github.io/blog/2010/08/10/php-connecting-tool-snoopy-introduction-and-applicat ...

  5. easyui datagrid动态修改editor时动态绑定combobox的数据

    需求在 datagrid 编辑框中开启一个combobox  ,但是里面的数据需要开启的时候才会知道,数据会根据其他因数变更 参考原文 :http://blog.csdn.net/donggua369 ...

  6. Jenkins+PowerShell持续集成环境搭建(二)控制台项目

    1. 新建一个名字为HelloWorld.Console的Freesyle项目: 2. 配置源码管理: 3. 编译配置: 版本:选择MSBuild4 文件:D:\CI\Config\HelloWorl ...

  7. 【python练习题】程序12

    #题目:判断101-200之间有多少个素数,并输出所有素数. #判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数. from math import ...

  8. 51-nod(1443)(最短路)

    解题思路:最短路+记录前驱和,刚开始一直以为是最短路+MST,结果发现,因为无向图的原因,有些边权很小的边再最短路处理后可能这条边也符合某两个点的最短路径,所以我们觉得这条边也是可以在MST处理中使用 ...

  9. Ubuntu18.04下安装Sublime Text3!

    这几天安装了Ubuntu18.04,然后在里面安装Sublime Text3,结果各种问题!各种BUG!试了网上各种办法!尼玛!都是坑爹的啊! 最后还是楼主自己解决了…… 废话不多说,直接按顺序执行下 ...

  10. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...