BZOJ 3782: 上学路线 [Lucas定理 DP]
3782: 上学路线
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 192 Solved: 75
[Submit][Status][Discuss]
Description
Input
Output
HINT
终于A掉了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+;
inline ll read(){
char c=getchar();ll x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
ll n,m,P;
int t;
struct Point{
ll x,y;
bool operator <(const Point &a)const{
return x<a.x||(x==a.x&&y<a.y);
}
}a[];
namespace A{
ll P=;
ll inv[N],fac[N],facInv[N];
void ini(){
inv[]=fac[]=facInv[]=;
for(int i=;i<=P;i++){
if(i!=) inv[i]=-P/i*inv[P%i]%P;
inv[i]+=inv[i]<?P:;
fac[i]=fac[i-]*i%P;
facInv[i]=facInv[i-]*inv[i]%P;
}
}
ll C(int n,int m){
if(n<m) return ;
return fac[n]*facInv[m]%P*facInv[n-m];
}
ll Lucas(ll n,ll m){
if(n<m) return ;
ll re=;
for(;m;n/=P,m/=P) re=re*C(n%P,m%P)%P;
return re;
}
ll f[];
void dp(){
for(int i=;i<=t;i++){
f[i]=Lucas(a[i].x+a[i].y,a[i].x);//printf("fo %d %lld\n",i,f[i]);
for(int j=;j<i;j++)
if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
f[i]=(f[i]- Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P +P)%P;
//printf("oh %d %lld %lld \n",j ,Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P ,f[i]);
//printf("f %d %lld\n",i,f[i]);
}
}
void solve(){
ini();
dp();
printf("%lld",f[t]);
}
}
namespace B{
ll P[]={,,,,};
const int N=1e5+;
ll Pow(ll a,ll b,ll P){
if(a==) return ;
ll re=;
for(;b;b>>=,a=a*a%P)
if(b&) re=re*a%P;
return re;
}
ll Inv(ll a,ll P){return Pow(a,P-,P);}
ll inv[N][],fac[N][],facInv[N][];
void ini(){
for(int j=;j<=;j++){
int MOD=P[j];
inv[][j]=fac[][j]=facInv[][j]=;
for(int i=;i<=MOD;i++){
if(i!=) inv[i][j]=-MOD/i*inv[MOD%i][j]%MOD;
if(inv[i][j]<) inv[i][j]+=MOD;
fac[i][j]=fac[i-][j]*i%MOD;
facInv[i][j]=facInv[i-][j]*inv[i][j]%MOD;
}
}
}
ll C(int n,int m,int j){//printf("C %d %d %d %lld %lld\n",n,m,j,fac[n][j],facInv[m][j]);
if(n<m) return ;
ll p=P[j];
return fac[n][j]*facInv[m][j]%p*facInv[n-m][j]%p;
}
ll lucas(ll n,ll m,int j){
if(n<m) return ;
ll MOD=P[],a=,p=P[j];
for(;m;m/=p,n/=p) a=a*C(n%p,m%p,j)%p;
return a*(MOD/p)%MOD*Inv(MOD/p,p)%MOD;
}
ll Lucas(ll n,ll m){//printf("Lucas1 %lld %lld\n",n,m);
ll re=,MOD=P[];
for(int i=;i<=;i++)
re=(re+lucas(n,m,i))%MOD;
return re;
} ll f[];
void dp(){
for(int i=;i<=t;i++){
f[i]=Lucas(a[i].x+a[i].y,a[i].x);//printf("fo %d %lld\n",i,f[i]);
for(int j=;j<i;j++)
if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
f[i]=(f[i]- Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%P[] +P[])%P[];
//printf("oh %d %lld %lld \n",j ,Lucas(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j] ,f[i]);
// printf("fn %d %lld\n",i,f[i]);
}
}
void solve(){
ini();
dp();
//for(int i=1;i<=t;i++)
// printf("Point %lld %lld %lld\n",a[i].x,a[i].y,f[i]);
printf("%lld",f[t]);
}
}
int main(){
freopen("in","r",stdin);
n=read();m=read();
t=read();P=read();
for(int i=;i<=t;i++) a[i].x=read(),a[i].y=read();
a[++t].x=n;a[t].y=m;
sort(a+,a++t);
if(P==) A::solve();
else B::solve();
}
BZOJ 3782: 上学路线 [Lucas定理 DP]的更多相关文章
- bzoj 3782 上学路线 卢卡斯定理 容斥 中国剩余定理 dp
LINK:上学路线 从(0,0)走到(n,m)每次只能向上或者向右走 有K个点不能走求方案数,对P取模. \(1\leq N,M\leq 10^10 0\leq T\leq 200\) p=10000 ...
- BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
我们枚举第一个经过的坏点,然后DP即可. 状态转移方程不是难点,难点在于组合数的处理. 将狼踩尽的博客中有很详细的证明过程,但是我只记住了结论 $n=a_1 * p^k+a_2*p^k-1...$ $ ...
- BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp
其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:$A[i]\equiv B[i](mod$ $P[i])$. 对于这个东西,你可以这么思考:如果最后能求出一个解,那么这个解的增量一定 ...
- BZOJ 3782 上学路线
首先这个题需要dp.dp[i]=C(x[i]+y[i],x[i])-Σdp[j]*C(x[i]-x[j]+y[i]-y[j],x[i]-x[j])(x[i]>=x[j],y[i]>=y[j ...
- bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP
1902: Zju2116 Christopher Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 172 Solved: 67[Submit][Stat ...
- [CTSC2017]吉夫特(Lucas定理,DP)
送70分,预处理组合数是否为偶数即可. 剩下的数据,根据Lucas定理的推论可得当且仅当n&m=n的时候,C(n,m)为奇数.这样就可以直接DP了,对于每个数,考虑它对后面的数的影响即可,直接 ...
- 洛谷P3773 [CTSC2017]吉夫特(Lucas定理,dp)
题意 满足$b_1 < b_2 < \dots < b_k$且$a_{b_1} \geqslant a_{b_2} \geqslant \dots \geqslant a_{b_k} ...
- Bzoj 4403: 序列统计 Lucas定理,组合数学,数论
4403: 序列统计 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 328 Solved: 162[Submit][Status][Discuss] ...
- BZOJ - 2142 礼物 (扩展Lucas定理)
扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...
随机推荐
- Springboot-shiro-redis实现登录认证和权限管理
Springboot-shiro-redis实现登录认证和权限管理 在学习之前: 首先进行一下Apache Shiro和Shiro比较: Apache Shiro是一个功能强大.灵活的,开源的安全框架 ...
- C语言函数的作用域规则
“语言的作用域规则”是一组确定一部分代码是否“可见”或可访问另一部分代码和数据的规则. “同一函数中,不同的结构体成员名能相同,当变量处于不同的作用域时,名称可以相同. 注:作用域,其对象是变量, ...
- c#简单操作MongoDB_2.4
一.MongoDB的安装 MongoDb在windows下的安装与以auth方式启用服务 二.下载驱动 使用nuget搜索“mongodb”,下载“MongoDB.Driver”(这是官方推荐的一个驱 ...
- Logger之Logger.getLogger(CLass)技巧代替system.out.print
---恢复内容开始--- 尊重原创:http://www.cnblogs.com/zxf330301/p/5876117.html 之前一直在使用System.out.println()来调试.但是用 ...
- 慕课网-前端JavaScrpt基础面试技巧-学习笔记
章节目录: JS基础知识(上)--讲解 JS 基础语法相关的面试题,分析原理以及解答方法.这一章节讲解了基础知识的第一部分:变量的类型和计算.以及JS "三座大山" -- 原型.作 ...
- [国嵌攻略][106][Linux内存管理子系统]
内存管理子系统 1.虚拟地址与物理地址的映射 2.物理内存的分配 Linux虚拟地址空间分布 设备最后访问的一定是物理地址,但Linux系统中使用的都是虚拟地址.虚拟地址简单的来说就是程序中使用的地址 ...
- Java数据持久层框架 MyBatis之背景知识一
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...
- es6重点笔记:Symbol,Set,Map,Proxy,Reflect
一,Symbol 原始数据类型,不是对象,它是JavaScript第七种数据类型,表示独一无二的值.Symbol是通过Symbol函数生成的: let s = Symbol(); typeof s / ...
- <p>标签样式设置
CSS中关于P标签中的样式: 1.font-family:浏览器在显示字体的时候,依次判断是否支持当前的字体,直到最后的字体系列. font-family:"宋体","仿 ...
- mysql 存在索引但不能使用索引的典型场景
mysql 演示数据库:http://downloads.mysql.com/docs/sakila-db.zip 以%开头的LIKE查询不能够利用B-tree索引 explain select * ...